Java 14 records canonical constructor

Brian Goetz brian.goetz at oracle.com
Thu Jun 4 19:39:03 UTC 2020


OK, this seems a totally different question to the one you initially 
asked :)

You're basically saying: why is a record constructor allowed to do 
_anything_ other than check invariants?

I understand where this desire comes from.  But, let's pull on that string.

Suppose you want to write a record like:

     record Rational(int num, int denom) { }

It seems pretty reasonable to want to normalize the numerator and 
denominator to lowest terms; among other things, this makes it easy to 
obtain the likely-desired invariant of `new Rational(1, 2)` equals `new 
Rational(2, 4)`.  Sure, you could export that responsibility on the 
client, or provide a separate factory `Rational::inLowestTerms`, but 
surely you see how that is more error-prone.

Suppose you have a record whose components are mutable (say, an array.)  
You might well want to perform a defensive copy on the way in (and, 
possibly on the way out, in the accessor.)

You might be willing to say "ban all these uses, they should all be 
illegal", and that would be a principled and defensible position. But 
surely you see as well that this would lead to less useful records.

Now, we struggled a lot with whether we can forbid the "bad" cases and 
keep the "good" cases.  This went about as well as you might expect.  So 
instead, we settled on allowing users to override accessors, to 
normalize arguments in the constructor, and to override equals, with the 
caveat that `java.lang.Record` imposes some stronger invariants on 
`equals()`, and you'd better maintain those.

> Sorry if this is going to far. I'm just looking for a way to ensure 
> that a record is really composed of just the record components such 
> that the canonical constructor can't alter anything to avoid 
> accidental bugs. If you say it's the programmers responsibility to 
> ensure this, I'm fine with that. I'd be curious to know what you want 
> to utilize this property of records for though :)



More information about the amber-dev mailing list