In Kotlin, the concept of inline/value classes (now referred to as value class) was introduced to minimize runtime overhead when working with wrappers over primitives and small structures. The idea is borrowed from other languages (e.g., C# structs), where such optimization is useful for enhancing performance without losing type safety.
Creating wrapper classes (e.g., for entity types or identifiers) without optimization leads to the creation of an additional object in memory, which affects performance, GC, and can lead to Boxing/Unboxing overhead. There is often a desire to have strict typing (e.g., UserId instead of Int), but without the actual creation of objects.
A value class is declared with the value modifier. In most situations, the JVM does not create an additional object — the value class is replaced with its field directly (inlining). This provides type safety and performance close to "just Int".
Code example:
@JvmInline value class UserId(val value: Int) fun showId(id: UserId) = println(id.value) val id = UserId(15) showId(id) // No separate UserId object is created
Key features:
Can value classes have multiple properties?
No, a value class can contain only one property.
// Error: // value class Money(val amount: Int, val currency: String)
Can you create a value class with a nullable property?
The value field of a value class cannot be nullable — only non-nullable types.
// Error: // value class Name(val value: String?)
Can inheritance be used with value classes?
Value classes do not support inheritance and cannot be abstract or sealed.
// Error: // value class NewId(val value: Int): BaseId()
A developer created a value class for an entity with two properties (e.g., a pair of Int and String) and received a compilation error.
Pros:
A developer uses a value class for an identifier type with one field (e.g., UserId), which works quickly and safely.
Pros: