/** * 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&trade;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]



Reply via email to