```@JvmInline value class MyInt(val n: Int)``` Why...
# getting-started
m
Copy code
@JvmInline value class MyInt(val n: Int)
Why do I need the
@JvmInline
annotation?
Also how are Kotlin `value class`es and Java value objects different?
c
Why do I need the
@JvmInline
annotation?
Value classes were added to Kotlin before they were added to Java. Because we want Kotlin to be compatible with Java, it was decided to future-proof by having two variants of value classes: With
@JvmInline
, it creates a value class handled by the Kotlin compiler, not compatible with Java. Added in Kotlin 1.3.
Copy code
@JvmInline
value class MyInt(val n: Int)
Without
@JvmInline
, it will create a value class handled by the JVM, compatible with Java.
Copy code
value class MyInt(val n: Int)
This kind of value class is not yet available because Java's value objects are not released yet (targeted for Java 28 as far as I can see).
👍 1
how are Kotlin `value class`es and Java value objects different?
With
@JvmInline
, the compiler removes the class wherever it can (TL;DR everywhere except generics and supertypes). More info in the documentation: kotlinlang.org/docs/inline-classes.html Without
@JvmInline
, it will be compiled to a Java value object. Since value objects are not released yet, this is not yet implemented and is currently being discussed. You can see the (tentative) specification here: • github.com/Kotlin/KEEP/blob/…/KEEP-0453-better-immutability-value-classes… • github.com/Kotlin/KEEP/blob/…/KEEP-0454-better-immutability-value-classes…
m
@CLOVIS So in summary: • With
@JvmInline
, the type is ‘not compatible’ with Java. • Without
@JvmInline
, it’ll match whatever Java ends up shipping. Right? What does it mean for a
@JvmInline value class
to be ‘not compatible’ with Java though? It’s invisible to Java code? Or it’s costly?
c
Right?
Yes.
It’s invisible to Java code?
Java can see a class `MyInt`but cannot call its constructor. Java cannot call methods that take a
MyInt
as parameter. For example a method
Copy code
fun foo(a: MyInt) {
    println("hello world ${a.a}")
}
is compiled on the JVM to
Copy code
public final class InlineKt {
   public static final void foo_cflvL_8(int a) {
      System.out.println("hello world " + a);
   }
}
The function
foo_cf1vL_8
is "special", the Java compiler will not let you call it even if you try.
You can allow Java to call a function that takes a value class as parameter with
@JvmName
, see kotlinlang.org/docs/inline-classes.html#…
In the future, there will be
Copy code
@JvmInline
@JvmExposeBoxed
value class MyInt(val a: Int)
which is exactly the same as
@JvmInline value class
for Kotlin users but is visible as a regular
class
for Java/Scala/etc users. See github.com/Kotlin/KEEP/blob/…/jvm-expose-boxed.md This will probably only really be useful for users of
@JvmInline value class
in libraries that want their code to be available to Java but without making breaking changes.
m
targeted for Java 28 as far as I can see
As the first preview release, yes. When they will become stable, we have no idea atm. Very optimistic plans are JDK 29 (the next LTS), we'll see whether this happens or not.
🙏 1
And thanks to @CLOVIS for a great explanation!
🫡 1
➕ 2
c
Very optimistic plans are JDK 29 (the next LTS)
Is there any chance that happens? 😅 That seems like a very short timeframe
Though I guess since it's basically only stuff within the JVM they can change it later without breaking changes?
m
The chances are somewhat low right now, but my intuition tells me Java folks will try to push for it, as LTS releases are adopted much-much better than non-LTS ones. If they miss this window, the next one is in 2 years. And the main thing they need to care about is "it works correctly", not "it works fast"; they can afford not optimizing value classes in many cases, but they need to guarantee they work as expected. If they can be relatively sure they work OK after preview in 28, they could go towards GA release in 29.
👍 1
c
Do you have an idea what's the timeframe after that on the Kotlin side?
m
Tentatively: we are currently planning to stabilize the core full value classes before or around the same time as JDK 29 releases (2.7), with copy vars becoming stable some time after (2.8-2.9). The complicated bits are: when Android supports them (🤞relatively soon after), when Compose begins using and optimizing them (🤞soon-ish), when other platforms begin optimizing them (not very soon).
🙏 2
😍 2
c
So ~3 years from now
m
For the full end-to-end "everything everywhere all at once" -- yes, but I believe there will be enough stable parts before that to still make them useful in production code.
👍 2
👍🏾 1
m
That’s an awfully long time, but thanks a lot to you both for such a thorough answer and explanation!
c
That's also why
@JvmInline
was added in 1.3 (2018!), we all knew value classes would take years to be properly added to the JVM and it was worth it having a limited variant early. I'm not sure anyone thought it'd be a 10 years gap though 😅
m
It's going to be even longer, the KEEP about that is coming (spoilers) 😃
❤️ 1
c
There's something after
copy var
?? 👀
m
That's another KEEP 😃 Also will come as soon as I have time to finalize it kodee sad