Draft specification for java.lang.Record

Kevin Bourrillion kevinb at google.com
Thu Aug 15 21:26:51 UTC 2019


On Thu, Aug 15, 2019 at 1:47 PM Brian Goetz <brian.goetz at oracle.com> wrote:

> /** * 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
> ..."
>

Yeah, I just felt it's useful information to any person perusing the class
docs as well.

 * <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.
>

I confess I don't know the better way either. Maybe an additional sentence
saying "Transparency means that...".

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."
>

Well, *someone *would think that. But I don't know, insert "*as if by*" in
the right place and maybe we're fine.

     * @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.
>

Hmm, do you want to say something more direct about that then?


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

Perhaps mention that the output does incorporate the component names.

:-)

Cool. Is it worth calling this out? Note: I don't want to specify the exact
form; it's just that the reader's gotta decide whether to accept the
default implementation or not somehow.

Perhaps Record.toString() and Enum.toString() ought to carry a warning that
their output may change when a component/field is renamed. We generally
want to assume (in the absence of reflection) that renaming something along
with all its references is strictly behavior-preserving.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20190815/a3819185/attachment.html>


More information about the amber-spec-experts mailing list