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