Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are Kotlin value classes different from inline classes?

Tags:

kotlin

What's the difference between an inline class and a value class? I understand that a value class is an inline class when it is annotated as @JvmInline value class but this only applies when targeting the JVM. So on other platforms, are all value classes implicitly inline classes? What exactly is a non-inline value class, and is what is the use of defining a value class without @JvmInline on the JVM?

like image 827
Klitos Kyriacou Avatar asked Jan 27 '26 14:01

Klitos Kyriacou


1 Answers

If you want to understand in more details, you can take a look at the corresponding KEEP.

What's the difference between an inline class and a value class?

You can see value classes as a more general declaration from the developer, while "inline" is more an implementation detail of how this is compiled.

When you declare a value class, you essentially give up on the identity of instances of this class. This means you cannot distinguish between identical references and equal values of that class. This is mostly why other restrictions follow from this declaration (like no var properties or === operator).

A good example to keep in mind is Int. You cannot distinguish between x and y if they are defined like this: val x = 42 and val y = 41 + 1. They are equal in every way because it doesn't make sense to talk about references here. This is why === is prohibited on primitive classes like this (and thus on value classes).

Giving up identity is what opens the door for inlining or other optimizations, but value classes don't have to be implemented this way. In fact, even experimental inline classes were not always "inlined", there are cases where they have to be boxed just like Int (e.g. when used as a generic type parameter, or as a parent type).

So on other platforms, are all value classes implicitly inline classes?

From the explanation above, it might be a bit clearer that inlining is only one possible way of implementing such classes. Actually, it shouldn't really matter to the developer what the compiler uses behind the scenes on different platforms (it's just optimizations). But yeah, on Native and JS it's easier for the compiler to inline stuff. Take a look at this section of the KEEP for more info on platform specifics.

What exactly is a non-inline value class, and is what is the use of defining a value class without @JvmInline on the JVM?

These are not supported at the moment (you have to specify @JvmInline in Kotlin 1.5). Only the "inline" implementation strategy is used in 1.5. However, the Kotlin team wants to be able to later adopt potential other implementation strategies, like making use of Project Valhalla's new kinds of types. To do so in a backwards compatible way, it helps to have this annotation right now and allow to not specify it later. From the KEEP:

The @JvmInline annotation makes it explicit that something special with this class is going on in JVM, and it enables us to support non-annotated value class in the future Valhalla JVM by compiling them using the capabilities of the Project Valhalla.

like image 188
Joffrey Avatar answered Jan 31 '26 00:01

Joffrey