Draft specification for java.lang.Record

Brian Goetz brian.goetz at oracle.com
Thu Aug 15 20:47:40 UTC 2019

>     /** * This is the common base class of all Java language record
>     classes.
> Well, and /only/ record classes -- it can't be extended manually. It 
> seems useful to understand both necessity and sufficiency, though I 
> notice Enum also doesn't say this.

Right, that's something for the JLS to say: "it is a compile-time error ..."

>     * * <p>More information about records, including descriptions of the
> To the extent that the bare term "record" (without "class") has 
> meaning, that is still something that is always declared by a "record 
> class" anyway, so might it be clearer to always say "record classes"? 
> Just a thought.

Yes, I think its better to go this way than the other way.  We want to 
remind people that records are, first and foremost, classes.

>     * implicitly declared methods synthesized by the compiler, can be
>     * found in section 8.10 of * <cite>The Java™Language
>     Specification</cite>. * * <p>A <em>record class</em>is a shallowly
>     immutable, transparent carrier for
> Typical readers may wonder what "transparent" means here. (They may 
> also not understand shallow immutability, but that they can probably 
> look up.)

What's a better way to say this?   This goes back to "the state, the 
whole state, and nothing but the state"; a record shouldn't hide much 
from its clients.

>     * <p>The primary reasons to provide an explicit declaration for
>     the * canonical constructor or accessor methods are to validate
>     constructor * arguments, perform defensive copies on mutable
>     components, or normalize groups * of components (such as reducing
>     a rational number to lowest terms.)
> Is this intentionally excluding normalizing a single component?

No, will adjust.

> The floating-point issue jumped to my mind as well. But we really 
> don't want to have to call out such a fine-grained special case, so 
> something like "(boxing primitive values if necessary)" could do the 
> trick?
Semantically, that's right; I worried about Java developers and their 
allergy to boxing, and then tomorrow we'll contend with "records are 
slow, don't use them."

> The main danger of this behavior is arrays; is it worth giving that a 
> callout here?

Yes, probably.

> */
>     @Override public abstract boolean equals(Object obj);
>          /** * {@inheritDoc} * * @implNote * The implicitly provided
>     implementation returns a hash code value derived * by combining
>     the hash code value for all the components, according to * {@link
>     Object#hashCode()} for components whose types are reference types,
>     * or the primitive wrapper hash code for components whose types
>     are primitive * types.
> It's unclear to me why it's even worth saying any of this. It seems 
> like it's trying to communicate the fact that it's neither going to 
> randomly ignore some components, nor try to compute a hash code for a 
> component via some weird other means. But then, since it's not 
> specifying *how* exactly it will /combine/ the values, it's not really 
> guaranteeing it doesn't do those weird things anyway.

It is mostly an in-terrorum warning not to try to do fancy stuff 
(constrained by the desire to not overspecify the algorithm.) People 
will think its clever to redefine equals/hashCode to only consider a 
subset of fields, and they'll be surprised why frameworks then treat 
their records weirdly.

> Perhaps mention that the output does not incorporate the component names.
But it does:

jshell> record R(int x) { }
|  created class R

jshell> new R(3)
$2 ==> R[x=3]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20190815/f4f5a2ce/attachment-0001.html>

More information about the amber-spec-experts mailing list