blob: 18e309a1b25b4be920812fa017e4dd561cbd7308 [file] [view] [edit]
[Value-based Classes][value-based-classes] should not be used with operations
that rely on object identity including reference equality, identity hashing,
synchronization, or serialization.
[JEP 401][jep-401] introduces Value Classes and Objects as a preview feature in
Java 28. Many existing JDK types (such as primitive wrappers, `Optional`, and
`java.time` classes) are value-based and are migrating to become true value
classes.
Operations to avoid on value classes:
Synchronization and Monitors
: Value objects do not have an object monitor. Synchronizing on them or
calling `wait()`, `notify()`, or `notifyAll()` cannot provide mutual
exclusion (as the runtime may freely copy or recreate instances) and throws
`IdentityException`.
Weak, Soft, and Identity References
: Classes like `WeakReference`, `SoftReference`, and `PhantomReference` track
the lifecycle of a specific object instance in memory. Because value objects
can be flattened, inlined, or rematerialized by the JVM, tracking their
lifetime is meaningless.
Identity-Based Maps and Caches
: `IdentityHashMap`, `WeakHashMap`, and builder configurations like
`CacheBuilder.weakKeys()`, `CacheBuilder.weakValues()`,
`MapMaker.weakKeys()`, or `Caffeine.weakKeys()` rely on reference identity
(`==`) or reference queues. Value classes will not behave correctly with
identity lookup or weak eviction.
`System.identityHashCode(...)`
: `System.identityHashCode` computes a hash code based on object identity.
Value-based classes do not have persistent identity, so calling
`System.identityHashCode` on them is not equivalent to `val.hashCode()` and
produces unstable results across equal or re-boxed instances. Use
`Objects.hashCode(val)` or `val.hashCode()` instead.
[value-based-classes]: https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/doc-files/ValueBased.html
[jep-401]: https://openjdk.org/jeps/401