JvmInline (Inline) Class in Kotlin — What It Can and Can Not | by Ade Fruandta

Photo by Luke Thornton on Unsplash

If you just heard about JvmInline (Inline) Class, you can read articles below:

Let’s dig dive what JvmInline (Inline) can and can not with some code preview.

Can be only final and can not be open or abstract

// Correct
@JvmInline
value class ExampleInline(private val value: String)

// Incorrect
@JvmInline
open value class ExampleInline(private val value: String)
// Incorrect
@JvmInline
abstract value class ExampleInline(private val value: String)

Can be extend to Interface but can not extend to another Class

open class ExampleClass
interface ExampleInterface

// Correct
@JvmInline
value class ExampleInline(private val value: String) : ExampleInterface
// Correct
@JvmInline
value class ExampleInline(private val value: ExampleInterface) : ExampleInterface by value

// Incorrect
@JvmInline
value class ExampleInline(private val value: String) : ExampleClass

Can only have one immutable property (whether public or private) and can not have mutable property or multiple property

// Correct
@JvmInline
value class ExampleInline(
// One private immutable property
private val value: String
)
// Correct
@JvmInline
value class ExampleInline(
// One public immutable property
val value: String
)

// Incorrect
@JvmInline
value class ExampleInline(
// One private mutable property
private var value: String
)
// Incorrect
@JvmInline
value class ExampleInline(
// Multiple private mutable property
private var value1: String,
private val value2: String
)

Can declare properties but can not have properties with backing fields.

@JvmInline
value class ExampleInline(private val value: String)

// Correct
val length: Int
get() = value.length

// Incorrect
// Value class can't have properties with backing fields
private val id1: Int = 0
// Incorrect
// Value class can't have properties with backing fields
private var id2: Int = 0
// Incorrect
// Value class can't have properties with backing fields
private lateinit var id3: Int

Can declare functions and override toString function, but can not override equals and hashCode function

@JvmInline
value class ExampleInline(private val value: String)

// Correct
init
println("Init ExampleInline")

// Correct
fun greeting()
println("Hello $value")

// Correct
override fun toString(): String
return value

// Incorrect
// Member with the name 'equals' is reserved for future releases
override fun equals(other: Any?): Boolean
return super.equals(other)

// Incorrect
// Member with the name 'hashCode' is reserved for future releases
override fun hashCode(): Int
return super.hashCode()

Can compare by equals function, but can not by referential equality

fun main() 
val exampleInline1 = ExampleInline("ABC")
val exampleInline2 = ExampleInline("ABC")

// Correct
assertEquals(exampleInline1, exampleInline1)
// Correct
assertEquals(exampleInline1, exampleInline2)

// Incorrect
// expected:<ExampleInline(value=ABC)> but was:<ABC>
assertEquals(exampleInline1, "ABC")
// Incorrect
// Identity equality for arguments of types ExampleInline and ExampleInline is forbidden
assertEquals(exampleInline1 === exampleInline1)
// Incorrect
// Identity equality for arguments of types ExampleInline and ExampleInline is forbidden
assertEquals(exampleInline1 === exampleInline2)

val list = listOf(
exampleInline1, exampleInline2
)
val map = mapOf(
"1" to exampleInline1,
"2" to exampleInline2
)

// Correct
assertTrue(list.contains(exampleInline1))
// Correct
assertTrue(list.contains(ExampleInline("ABC")))
// Correct
assertTrue(list.contains(ExampleInline("ABC")))
// Correct
assertTrue(map.containsValue(exampleInline1))
// Correct
assertTrue(map.containsValue(ExampleInline("ABC")))

JvmInline (Inline) Class don’t have an identity and can only hold values. It because they are subset of value-based classes. And it will impact to the memory allocation as well. In example:

class ExampleActivity : AppCompatActivity() 

val exampleInline: ExampleInline = ExampleInline("")

val exampleNotInline: ExampleNotInline = ExampleNotInline("")

@JvmInline
value class ExampleInline(private val value: String)

class ExampleNotInline(private val value: String)

And when do heap dump memory:

ExampleInline can not be seen on memory allocation.

Can write code to initiate JvmInline (Inline) Class but can not be compiled

public void main() 
// We can write this code, but got error when build
ExampleInline exampleInline = new ExampleInline("ABC");

/*
Error when build
ExampleTest.java:9: error: cannot find symbol
ExampleInline exampleInline = new ExampleInline("ABC");
^
symbol: constructor ExampleInline(String)
location: class ExampleInline
*/

public void main()
// We can write this code, but got error when build
Constructor<ExampleInline> constructor = ExampleInline.class.getConstructor(String.class);
ExampleInline exampleInline = constructor.newInstance("ABC");

/*
ExampleInline.<init>(java.lang.String)
java.lang.NoSuchMethodException
*/

Always be seen as underlying value on Java code

fun String.toInline(): ExampleInline = ExampleInline(this)

@JvmName("greeting1") // to manually disable mangling and given name on the JVM
fun String.greeting()
println("Hello $this")

@JvmName("greeting2") // to manually disable mangling and given name on the JVM
fun greeting(value: String)
println("Hello $value")

@JvmName("greeting3") // to manually disable mangling and given name on the JVM
fun greeting(exampleInline: ExampleInline)
println("Hello $exampleInline")

Not if we implement an interface on inline class, it could be seen as the interface

interface ExampleInterface

@JvmInline
value class ExampleInline(private val value: String) : ExampleInterface

fun String.toInterface(): ExampleInterface = ExampleInline(this)

fun greeting(exampleInline: ExampleInterface)
println("Hello $exampleInline")

Next Post

4 Things To Ignore (and 3 Things To Do) in Your Next Content Audit

Have you set your written content promoting beneath the microscope? A content material audit does just that – helping you see how your company’s released content allows or hinders results. The comprehensive examination evaluates the impression of each piece of content material and the strategy as a total. It can […]
4 Things To Ignore (and 3 Things To Do) in Your Next Content Audit

You May Like