Java Object Identity Is a 30-Year Trap. JDK 28 Is Breaking It.

You know the pain. You write a simple data class in Java—maybe a 2D point or a currency amount—and suddenly you’re paying a massive tax in memory overhead and reference semantics. You just want a lightweight carrier for your data, but Java insists on giving every single instance a unique soul, a heap allocation, and an identity crisis.

For decades, we’ve been paying an identity tax on Java objects, even when they were just silent data carriers.

The OpenJDK team has officially proposed JEP 401 to target JDK 28, introducing Value Objects. If you read the headlines, you’ll think this is about performance. You’ll think it’s about flattening the heap and making your code run faster. It is, but that’s not the real story.

The real revolution isn’t happening in the JVM’s memory layout; it’s happening in your head. Value objects fundamentally shift Java from a reference-based model to a value-based semantics model. That means challenging decades of developer intuition. It means accepting that an object doesn’t actually need an identity to be useful.

The real revolution isn’t making your code run faster; it’s forcing developers to accept that an object without an identity is still an object.

As developers on HackerNews recently pointed out, we’ve been waiting for this paradigm shift for years, rehashing the same theoretical debates. But now it’s real. The tension here is massive: Java has to preserve backward compatibility with its deeply entrenched object-oriented identity model while simultaneously telling developers to unlearn their oldest habits.

It’s a tough pill to swallow. We’ve been trained to use == to check identity and equals() to check value. Value objects throw a wrench into this entire mental model because they strip away that unique reference identity. Two value objects with the same state are literally the same object. They have no independent life.

If you’re an architect or a Java developer, this isn’t just a syntax update. It changes how you design APIs, how you model data, and how you think about state across your entire ecosystem.

Backward compatibility is the chain keeping us anchored to old paradigms, and value objects are the key breaking us out.

Stop clinging to the idea that every piece of data needs a unique memory address. The boilerplate is dying, the overhead is vanishing, and the future of Java is finally shedding the weight of its own identity. Get ready to unlearn everything you thought you knew.

FAQ

Q: If objects don't have identity, how do I use == vs equals()?

A: With value objects, the distinction blurs. Because two value objects with the same state are fundamentally the same instance in terms of value semantics, you don't rely on reference identity anymore. You compare by state, which simplifies your code but destroys old habits.

Q: What's the practical implication for my APIs?

A: You can finally model lightweight data carriers without the memory bloat of traditional objects. This means cleaner APIs, less boilerplate, and massive performance gains when passing around large collections of simple data structures.

Q: Isn't this just reinventing C structs or primitive types?

A: Yes and no. It's bringing the performance of primitives to the object world, but keeping the object-oriented ergonomics. It's not a step backward to C; it's Java finally admitting that not everything needs to be a full-fledged, identity-bearing object.

📎 Source: View Source