I am trying to understand concept of inline classes - they are a simple object wrapper of single property that is being inlined during runtime. That means, that the actual initialization of the class is not happening at runtime
I was trying to write simple test which directly will show my above explanation during JUnit test as below:
companion object {
private const val NAME = "JACK"
}
inline class NameInlineClass(val value: String)
@Test
fun unwrapping() {
val nameInlineClass = NameInlineClass(NAME)
val name = nameInlineClass
assertEquals(name, NAME)
}
This test fails unfortunately which leads me to the question why during assertEquals()
the actual unwrapped String value is not being compared, but the actual inline class (which should be unwrapped during runtime)?
What you probably wanted to do was
val name = nameInlineClass.value
, but I'll try to explain the error.See Representation from docs (includes code sample):
That means as long as you don't reference the wrapping object or its type explicitly, value will not be boxed. We can check it by inspecting bytecode (decompiled back to Java for readability):
I won't paste entire generated
NameInlineClass
body, butconstructor-impl
is static method that only checks fornull
ofvalue
, andbox-impl
creates the wrapper object.You can see
nameInlineClass
is indeed aString
- that means inline works and no extra object was allocated.Only when you reference
nameInlineClass
instead ofnameInlineClass.value
compiler determines that this object needs representation and "boxes" the value with wrapperNameInlineClass
class.