A value class is a specialized Kotlin class designed to wrap a single underlying value, providing compile-time type safety while eliminating the runtime overhead of object allocation. During compilation, the Kotlin compiler aggressively inlines the wrapped value, replacing object instantiations with the underlying primitive or reference type in the generated bytecode.Documentation Index
Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
Use this file to discover all available pages before exploring further.
Syntax
To declare a value class on the JVM backend, use thevalue modifier combined with the @JvmInline annotation.
Structural Constraints
Value classes are subject to strict structural limitations to ensure the compiler can safely inline them:- Primary Constructor: Must contain exactly one read-only (
val) property. Mutable properties (var) are not permitted. - Backing Fields: Cannot declare additional properties with backing fields. All secondary properties must be computed via custom getters.
- Inheritance: Value classes are implicitly
final. They cannot extend other classes, nor can they be extended. - Interfaces: They are permitted to implement interfaces.
- Initialization: They can contain
initblocks for validation logic. - Identity and Equality: Referential equality checks (
===and!==) are strictly prohibited by the compiler. Because value classes can be boxed and unboxed freely by the compiler, they do not possess a stable runtime identity. Only structural equality (==and!=) is permitted, which evaluates the underlying wrapped values.
Runtime Representation: Boxing and Unboxing
The compiler dynamically determines whether to use the unboxed (underlying) value or a boxed (instantiated object) representation based on the call site context.- Unboxed: When the value class is used as a concrete, statically typed variable or function parameter, the compiler uses the underlying type. No object allocation occurs.
- Boxed: When the value class is used in a context that requires polymorphism—such as being assigned to an interface type or passed to a generic type parameter (
<T>)—the compiler allocates a wrapper object on the heap. - Nullable Types: Boxing behavior for nullable value classes depends entirely on the underlying type. If the underlying type is a primitive (e.g.,
Int), using the value class as a nullable type forces boxing because JVM primitives cannot natively representnull. Conversely, if the underlying type is a reference type (e.g.,String), the nullable value class is represented as a nullable reference (String?) under the hood, requiring no boxing.
Name Mangling
Because value classes are erased to their underlying types at the bytecode level, function overloading can lead to platform declaration clashes.authenticate-<hash>(String)). This ensures distinct bytecode signatures for the JVM while maintaining the original, clean function names in the Kotlin source code.
Master Kotlin with Deep Grasping Methodology!Learn More





