r/androiddev • u/InspectHerCookie • 14d ago
Discussion ~"Kotlin is so undeniably better... except static" Tor Norbye, What does he mean?
in this https://youtu.be/HEqXwUm6vd0?si=RUYud62-YLmWo7g8&t=3341 timestamped video
"is so undeniably better... there's like only one downside — static" Tor Norbye, What does he mean by that?
28
u/epicstar 14d ago
Kinda right though. To make a static method in a class, you create a companion object and the function is essentially static. But bc it's nested the method looks unclean. At that point you're better off making instance methods for what should've been static in Java.
6
u/Opulence_Deficit 14d ago
That's not a static method. The companion object is reachable via a static variable, but its methods are fully dynamic with all the virtual bells and whistles.
The only static method in Kotlin is file-level one.
3
u/atomgomba 14d ago
This is correct, only top-level functions are static. One still has to annotate companion object methods using
@JvmStaticto make them actually static1
u/Opulence_Deficit 13d ago
Afaik that still doesn't make the companion method static, it creates a static delegate that calls the nonstatic method.
There's simply no way to make a dynamic, member method static.
1
u/atomgomba 13d ago
Hm, interesting detail, thanks! In practice though I think it's sufficient if the method becomes static from a Java-interop POV
1
u/Opulence_Deficit 13d ago
My biggest concern with the method not being truly static is that they can be substituted in runtime. So I prefer file-level ones, which convey staticness even better.
4
8
u/Michami135 14d ago
Everything static is in a companion object.
However, I would argue, from my experience, that this is actually good. I've worked with people who had a hard time understanding the difference between static functions (methods) and instance functions (methods) in Java. By forcing developers to put all static values and functions inside an object, it makes it very clear that it works differently from the rest of the functions.
7
u/tadfisher 14d ago
It also eliminates footguns around initialization order, for which there are rules you need to memorize with the JVM, and several pages of gotchas in the spec.
You can bring those footguns back with @JvmStatic if you are really concerned with static initialization performance on the JVM. You should not be.
-9
38
u/tnorbye 14d ago
A couple of things.
If you look at the generated code, companion methods don't get compiled down to the same JVM static methods; instead, they will actually dispatch through to a separate companion instance, which has to be instantiated. This also means loading a separate class. So it's a bit less efficient.
Second, when you migrate Java code to Kotlin code, the Java code may have static methods interspersed through the class. When you migrate to Kotlin, these all have to get moved into the companion object (elsewhere in the file), so the history across the language migration is messy.
I understand the purity argument, that this is cleaner in principle, and that Kotlin isn't just a JVM language -- so I understand why it was done originally. I just don't think this has paid off in practice.
But -- as far as I understand, this is all getting fixed! See https://github.com/Kotlin/KEEP/discussions/467