/** * 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]