Are Java records intended to eventually become value types?

The record preview feature (JEP 384) introduced in JDK 14 are a great innovation. They make it much easier to create simple immutable classes that are a pure collection of values without the loss of context inherent in the generic tuple classes in various libraries.

The description of the JEP, written by Brian Goetz ( explains the intent very well. However I was expecting a closer association with the eventual introduction of value types. The original aims of value types were quite extensive: essentially allowing potentially significant performance improvements for objects whose value is all that matters by removing all the overhead not required for these types of object (e.g. reference indirection, synchronisation). Plus it could provide syntactical niceties such as myPosition != yourPosition instead of !myPosition.equals(yourPosition).

It seems as though the restrictions of records are very close to the types of restrictions that would be required on a potential value type. Yet the JEP makes no reference to these aims in the motivation. I tried unsuccessfully to find any public records on these deliberations.

So my question is: are records intended to be part of a possible move towards value types or are these completely unrelated concepts and future value types may look completely different?

My motivation for asking the question: if records become a permanent part of the language it would be an added incentive to adopt them in code if there is the possibility of significant performance benefits in a future release.


Records and primitive classes (the new name for value types) have a lot in common — they are implicitly final and shallowly immutable. So it is understandable that the two might be seen as the same thing. In reality, they are different, and there is room for both of them to co-exist, but they can also work together.

Both of these new kinds of classes involve some sort of restriction, in exchange for certain benefits. (Just like enum, where you give up control over instantiation, and are rewarded with a more streamlined declaration, support in switch, etc.)

A record requires you to give up on extension, mutability, and the ability to decouple the representation from the API. In return, you get implementations of constructors, accessors, equals, hashCode, and more.

A primitive class requires you to give up on identity, which includes giving up on extension and mutability, as well as some other things (e.g., synchronization). In return, you get a different set of benefits — flattened representation, optimized calling sequences, and state-based equals and hashCode.

If you are willing to make both compromises, you can get both sets of benefits — this would be a primitive record. There are lots of use cases for primitive records, so classes that are records today could be primitive records tomorrow, and would just get faster.

But, we don’t want to force all records to be primitive or for all primitives to be records. There are primitive classes that want to use encapsulation, and records that want identity (so they can organize into trees or graphs), and this is fine.

Leave a Reply

Your email address will not be published. Required fields are marked *