liveBook · Manning

Inline class

As explained in Kotlin in Action, 2E

An inline class is a Kotlin class with exactly one primary-constructor property whose values are represented by the underlying property type wherever possible rather than by allocated wrapper objects.

An inline class adds a distinct type to a value such as an amount without normally allocating a wrapper object. This prevents callers from confusing values with different meanings, such as USD cents and Japanese yen, while avoiding the repeated allocation cost of an ordinary wrapper class. section 4.5

Wrapping an expense amount

@JvmInline value class UsdCent(val amount: Int) fun addExpense(expense: UsdCent) { // save the expense as USD cent } fun main() { addExpense(UsdCent(147)) } section 4.5

The declaration and its runtime behavior work together:

  • Mark the class with value and annotate it with @JvmInline. section 4.5
  • Give the class exactly one primary-constructor property, which supplies the underlying representation. section 4.5
  • Use the wrapper type in function signatures to make incompatible meanings harder to pass accidentally. section 4.5
  • Expect the underlying type wherever possible; the wrapper must remain in some cases, notably when used as a type parameter. section 4.5
interface PrettyPrintable {
   fun prettyPrint()
}

@JvmInline
value class UsdCent(val amount: Int): PrettyPrintable {
   val salesTax get() = amount * 0.06
   override fun prettyPrint() = println("${amount}¢")
}

fun main() {
   val expense = UsdCent(1_99)
   println(expense.salesTax)
   // 11.94
   expense.prettyPrint()
   // 199¢
}

An inline class can expose computed properties and implement an interface while retaining its wrapped-value representation where possible. section 4.5

How Kotlin in Action, 2E covers it

How deep it goes
Explains declaration syntax, semantic motivation, runtime representation, and the type-parameter case requiring the wrapper.
Examples
Uses expense amounts, USD cents, Japanese yen, sales tax, and pretty-printing to demonstrate the feature.
What it assumes
Assumes familiarity with Kotlin classes, primary constructors, function parameters, and compiler-generated code.
What you can do after
Apply Kotlin value classes to distinguish domain values without routinely allocating wrapper objects.
How it connects
Connects wrapper types, underlying types, type parameters, and interfaces.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.