ProgrammingBackend Developer

What are inline classes (value classes) in Kotlin, what are they used for and what limitations exist when using them?

Pass interviews with Hintsage AI assistant

Answer.

History of the Issue

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.

Problem

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.

Solution

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:

  • The class must contain exactly one property (val or var), but this type cannot be nullable
  • No inheritance support (value classes cannot inherit or be inherited)
  • Some limitations: you cannot have an init block, store lateinit or uninitialized properties, you cannot use reflection in all cases

Tricky Questions.

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()

Typical Mistakes and Anti-patterns

  • Attempting to use value classes for complex structures (e.g., with multiple fields)
  • Storing nullable values through value classes
  • Using reference methods (e.g., equals/hashCode methods may behave unexpectedly in the compiled backend

Real-life Example

Negative Case

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:

  • Attempts to achieve strict typing Cons:
  • Does not work, cannot compile

Positive Case

A developer uses a value class for an identifier type with one field (e.g., UserId), which works quickly and safely.

Pros:

  • Concise and safe code
  • No runtime overhead Cons:
  • Can only be used with one non-nullable type