跪拜 Guibai
← All articles
Kotlin · Android

Kotlin 2.5 Lets Value Classes Hold Multiple Properties

By RockByte ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

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.

Summary

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.

Takeaways
— Kotlin 2.5.0-Beta2 adds full value classes that can have multiple properties; they have no instance identity and the compiler rejects `===` on them.
— Full value classes auto-generate `equals()`, `hashCode()`, and `toString()`, but not `componentN()` or `copy()`.
— Abstract value classes and value objects (declared with `value object`) are supported.
— Enable the experimental feature with the `-Xfull-value-classes` compiler option.
— Future Kotlin versions will require explicit `inline` or `@JvmInline` for inline value classes; Kotlin 2.5.20 emits a warning and 2.6.0/2.7.0 turns it into an error.
— Library authors can use the experimental `@WillBecomeValue` annotation to warn users when their code depends on identity.
Conclusions

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.

Concepts & terms
Full value class
A value class that can have multiple properties and has no instance identity. The compiler generates equals/hashCode/toString but not copy or componentN.
Value object
A value class with no properties, declared with `value object`, representing a single possible value such as a state or token.
@WillBecomeValue
An experimental annotation for library authors to signal that a class may become a value class in the future, causing the compiler to warn if user code depends on identity.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗