Kotlin 2.5 Lets Value Classes Hold Multiple Properties
Kotlin's new full value classes remove the ability to compare values by reference, which changes how developers model domain objects and may affect libraries that depend on reference identity. At the same time, the migration to explicit inline markers will break existing `value class` declarations unless updated.
Kotlin 2.5.0-Beta2 adds full value classes: value classes that can hold multiple properties and have no instance identity. Previously, any multi-property type had to use a data class or regular class, both of which allow `===` to distinguish equal objects. That's meaningless for value types like coordinates, and it blocks optimizations. Full value classes reject `===` on their values, so two equal instances are indistinguishable. The compiler generates `equals()`, `hashCode()`, and `toString()`, but not `componentN()` or `copy()`.
Abstract value classes and value objects (via `value object`) are included. The feature is experimental, enabled with `-Xfull-value-classes`.
Bare `value class` will no longer imply inline. The compiler will require explicit `inline` or `@JvmInline` for inline value classes, with a warning in 2.5.20 and an error in 2.6.0/2.7.0. Library authors can use `@WillBecomeValue` to alert users when identity dependence will break.
By rejecting `===` on full value classes, Kotlin gives value semantics a hard guarantee; developers no longer need to remember to use `equals()` instead of identity for these types.
The phased migration plan is a deliberate break: keeping `value class` as inline by default would have made the new multi-property feature ambiguous, so the Kotlin team is forcing a clear split with warnings first.
The different handling by Spring and serialization libraries means switching a type from inline to full value class can change behavior in ways that aren't visible at compile time; teams should test those boundaries.