Draft specification for java.lang.Record
Alex Buckley
alex.buckley at oracle.com
Thu Aug 15 19:14:04 UTC 2019
I am reading this javadoc from the POV of someone in 2034 (15 years
hence, like we are 15 years from Enum) who doesn't know anything about
Amber.
On 8/15/2019 10:34 AM, Brian Goetz wrote:
> /**
> * This is the common base class of all Java language record classes.
I know this borrows from Enum, but "base class" is a terrible un-Java
phrase there and it's terrible here. "This is the common superclass of
all record classes in the Java language."
> *
> * <p>More information about records, including descriptions of the
> * implicitly declared methods synthesized by the compiler, can be
> * found in section 8.10 of
> * <cite>The Java™ Language Specification</cite>.
Too much too soon; drop.
> *
> * <p>A <em>record class</em> is a shallowly immutable, transparent
> carrier for
> * a fixed set of values, called the <em>record components</em>. The
> Java™
> * language provides concise syntax for declaring record classes,
> whereby the
> * record components are declared in the record header. The list of record
> * components declared in the record header form the <em>record
> descriptor</em>.
Are classes immutable, or objects? I think "shallowly immutable" belongs
in a paragraph about "records" or "record instances" (not "record
classes") that is not yet written, but should appear just before "For
all record classes, ..."
> *
> * <p>A record class has the following mandated members: a public
> <em>canonical
> * constructor</em>, whose descriptor is the same as the record descriptor;
"A record class has a public canonical constructor, whose signature is
the same ...;"
> * a private ... field corresponding to each component, whose name and
> * type are the same as that of the component; a public accessor method
> * corresponding to each component, whose name and return type are the
> same as
> * that of the component. If not explicitly declared in the body of
> the record,
Prefer "; and a public _no-args_ accessor method corresponding ... Any
or all of these elements may be declared explicitly; if one is not
declared explicitly, then it is provided implicitly."
> * implicit implementations for these members are provided.
> *
> * <p>The implicit declaration of the canonical constructor initializes the
> * component fields from the corresponding constructor arguments. The
> implicit
> * declaration of the accessor methods returns the value of the
> corresponding
> * component field. The implicit declaration of the {@link
> Object#equals(Object)},
> * {@link Object#hashCode()}, and {@link Object#toString()} methods are
> derived
> * from all of the component fields.
> *
> * <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.)
> If any
> * of these are provided explicitly.
Can't grok "mutable components". Do you mean the (mutable) constructor
arguments which correspond to components?
Prefer ", or cross-check the values of different components." instead of
normalizing and reducing which again is hard to follow.
Expecting: "An instance of a record class is _shallowly immutable_,
which means ..."
> *
> * <p>For all record classes, the following invariant must hold: if a
> record R's
> * components are {@code c1, c2, ... cn}, then if a record instance is
> copied
> * as follows:
Calling `R` a "record" is obtuse since the invariant is about "record
classes" and this whole spec outlines a "record class". There should be
two kinds of entity -- "record class" and "record instance", or "record
class" and "record" -- not three. Also, "Given a non-null instance `r`
of record class `R`, whose components are ..., then if `r` is copied in
the following way:"
> * <pre>
> * R copy = new R(r.c1(), r.c2(), ..., r.cn());
> * </pre>
> * then it must be the case that {@code r.equals(copy)}.
A name like "copy equality" or "by parts equality" or "component
equality" would be helpful for this property, both for the spec of
equals and for developers' general knowledge.
Cloning: if a record class was to implement Cloneable, then the
inherited implementation of Object::clone would not preserve copy
equality (because, yes, cloning is not the same as copying). Recommend
not implementing Cloneable?
Alex
More information about the amber-spec-experts
mailing list