Data Oriented Programming, Beyond Records

David Alayachew davidalayachew at gmail.com
Thu Jan 15 04:07:30 UTC 2026


Thanks @Robbe Pincket <robbepincket at live.be> and @Brian Goetz
<brian.goetz at oracle.com>. My understanding of the examples was a little off.

So, the difference between records and carrier classes is that carrier
classes force you to describe the internal state representation everytime,
whereas records can derive that from the stuff in parentheses.

For example, carrier classes don't have a "default" internal representation
that you can override -- you must provide the internal representation every
time. Whether the internal representation is mutable fields or immutable,
whether the internal representation is private or package-protected or
protected, etc. Carrier classes give you no defaults on the internal field
representation -- you must decide all of that *explicitly*.

Upon doing so, then carrier classes can give you basically every other
default for free, straight from the records handbook. But it's only the
internal field representation where you are on your own.

Do I have it right this time? Obviously, there are things like the class
must be final and extend Record, but I'm more focusing on the internal
state details.

On Wed, Jan 14, 2026 at 8:00 PM Brian Goetz <brian.goetz at oracle.com> wrote:

> AFAIK `final class Point2D(int x, int y) {}` does not work? You need the
> following:
>
> ```java
> class Point(int x, int y) {
>     private final component int x;
>     private final component int y;
> }
> ```
> So that's the benefit. No need to specify the fields a second time.
>
>
> If you want it to be equivalent to the record declaration, you also have
> to make the class final (and extend Record.)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20260114/aee5f717/attachment-0001.htm>


More information about the amber-spec-observers mailing list