Limitations
What value classes cannot do.
Limitations is a free Kotlin Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Kotlin Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Knowing the Boundaries
Value classes are powerful but constrained. Understanding their limits helps you choose the right tool and avoid surprises.
Exactly One Property
A value class wraps a single value. To group multiple fields you need a regular class or a data class.
// @JvmInline value class Range(val lo: Int, val hi: Int) // not allowed
data class Range(val lo: Int, val hi: Int)
fun main() {
println(Range(1, 10))
}No init-State Beyond the Value
Value classes cannot have backing fields other than the single constructor property. Extra var state with a backing field is not allowed.
@JvmInline
value class Counter(val value: Int) {
// val cached: Int = value * 2 // not allowed: extra backing field
val doubled: Int get() = value * 2 // computed is fine
}
fun main() {
println(Counter(3).doubled)
}No Inheritance
Value classes are implicitly final. They cannot extend other classes and cannot be extended. They may only implement interfaces.
interface Named { val label: String }
@JvmInline
value class Tag(val text: String) : Named {
override val label: String get() = text
}
fun main() {
println(Tag("urgent").label)
}Boxing Costs Return
The zero-overhead promise vanishes when the value is used as a nullable, generic, or interface type. The compiler then boxes it into a real object.
@JvmInline
value class Id(val raw: Int)
fun main() {
val list: List<Id> = listOf(Id(1), Id(2)) // boxed inside the list
println(list.map { it.raw })
}No Identity
Value classes have no stable referential identity. Reference equality with === is meaningless, and they cannot be used where object identity matters (such as a synchronization lock).
@JvmInline
value class Code(val value: Int)
fun main() {
val a = Code(5)
val b = Code(5)
println(a == b) // structural equality works
}Cannot Be lateinit or Delegated
You cannot apply lateinit to the underlying value, and value classes do not support property delegation on their single field. The value must be set in the constructor.
@JvmInline
value class Slug(val value: String)
fun main() {
val s = Slug("hello-world") // must be provided up front
println(s.value)
}JVM Naming Mangling
On the JVM, functions taking value class parameters get mangled names in bytecode to avoid clashes. This complicates Java interop; Java callers may not see them cleanly.
@JvmInline
value class Hz(val value: Int)
fun tune(freq: Hz) = freq.value
fun main() {
println(tune(Hz(440))) // simple from Kotlin; mangled from Java
}Not for Multi-Field Wrappers
If you find yourself wishing for two properties, a value class is the wrong tool. Reach for a data class, accepting the allocation in exchange for richer structure.
data class Coordinate(val lat: Double, val lng: Double)
fun main() {
println(Coordinate(41.0, 29.0))
}Limitations Summary
Value classes cannot:
- Hold more than one property
- Have extra backing fields or
lateinit - Inherit from or be inherited by classes
- Offer referential identity
- Always avoid boxing
Choosing Wisely
Use a value class for a single, validated, type-safe value. Use a data class for grouped data. Use a type alias for pure readability with no safety. Each has its place.
Quick Check
Test your understanding of value class limitations.
Recap
You learned value class limitations:
- Single property, no extra backing fields
- No inheritance, no identity
- Boxing returns for nullable/generic/interface use
- JVM name mangling complicates Java interop
Match the tool to the need.
Frequently asked questions
Is the “Limitations” lesson free?
Yes — the full text of “Limitations” is free to read here on the web, and the Kotlin Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Kotlin Academy course, upgrade to CoddyKit PRO.
What will I learn in “Limitations”?
What value classes cannot do. You practise Kotlin Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Kotlin Academy?
No prior experience is required. Kotlin Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Limitations” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Kotlin Academy lesson?
Yes. Every Kotlin Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Type Aliases
- Inline Value Classes
- Use Cases
- Limitations