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

Reply via email to