This raises a related question, which is: what if the author likes the default
implementation, but wants to add more annotations (or Javadoc)?
Currently, the story is decent for constructors; declaring an empty `Foo { }`
constructor recreates the default behavior. There is no equivalent for
accessors, equals, hashCode, or toString. We toyed with a “default.m()” syntax
in the past:
record R(int x, int y) {
@MyAnnotation
public boolean equals(Object o) -> default.equals(o);
}
which doesn’t seem so bad, and is surely better than trying (and maybe failing)
to reproduce the default behavior imperatively.
> On Mar 9, 2019, at 12:47 PM, Brian Goetz <[email protected]> wrote:
>
> This came up before, but we didn’t reach a conclusion.
>
> A record component is more than just the lower-level members (fields,
> accessors, ctor params) it gets desugared too. So it seems reasonable that
> it be considered an annotatable program element, and that reflection expose
> directly the annotations on record components (separately from any
> annotations on the class members that may or may not derive from desugaring
> of records.)
>
> But, that still leaves the question of whether the desugaring should, or
> should not be, transparent to annotations. My sense is that pushing
> annotations down to fields, ctor params, and accessors _seems_ friendly, but
> also opens a number of uncomfortable questions.
>
> - Should we treat the cases where @A has a target of RECORD_COMPONENT,
> separately from the cases where it does not, such as, only push the
> annotation down to members when the target does not include RECORD_COMPONENT?
> That is, is the desire to push down annotations based on “well, what if we
> want to apply a “legacy” annotation? If so, this causes a migration
> compatibility issue; if someone adds RC to the targets list for @A, then when
> the record is recompiled, the location of the annotations will changed,
> possibly changing the behavior of frameworks that encounter the record.
>
> - What if @A has a target set of { field, parameter }, but for some reason
> the user does _not_ want the annotation pushed down? Tough luck? Redeclare
> the member without the annotation?
>
> - If the user explicitly redeclares the member (ctor, accessor), what
> happens? Do we still implicitly push down annotations from record components
> to the explicit member? Will this be confusing when the source says “@B int
> x() -> x”, but reflection yields both @A and @B as annotations on x()?
>
> All of which causes me to back up and say: what is the motivation for pushing
> these down to implicit members, other than “general friendliness”? Is this
> a migration strategy for migrating existing code to use records, without
> having to redeclare annotations on the members? And if so, how useful is it
> really? Will users want to throw the union of field/accessor/ctor parameter
> annotations on the record components just to gain compatibility with their
> existing code?
>
> My gut sense is that the stable solution is to make record component a new
> kind of target, and encourage frameworks to learn about these, rather than
> trying to fake out frameworks by emulating legacy behavior.
>
>
>> On Mar 8, 2019, at 8:43 PM, Kevin Bourrillion <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> Re: annotations,
>>
>> Doc says, "Record components constitute a new place to put annotations;
>> we'll likely want to extend the @Target meta-annotation to reflect this."
>>
>> I'm sure we discussed this before, but I also expect to be able to put any
>> METHOD-, FIELD- or PARAMETER-targeted annotation on a record component, and
>> have that annotation appear to be present on the synthesized
>> accessor/field/constructor-parameter. Is that sensible?
>>
>> (As for records themselves, I expect they are targeted with TYPE just as
>> enums/interfaces/"plain old classes" (jeesh, is there any term that means
>> the latter?).)
>>
>>
>>
>>
>>
>>
>>
>> On Fri, Mar 1, 2019 at 12:16 PM Brian Goetz <[email protected]
>> <mailto:[email protected]>> wrote:
>> I've updated the document on data classes here:
>>
>> http://cr.openjdk.java.net/~briangoetz/amber/datum.html
>> <http://cr.openjdk.java.net/~briangoetz/amber/datum.html>
>>
>> (older versions of the document are retained in the same directory for
>> historical comparison.)
>>
>> While the previous version was mostly about tradeoffs, this version
>> takes a much more opinionated interpretation of the feature, offering
>> more examples of use cases of where it is intended to be used (and not
>> used). Many of the "under consideration" flexibilities (extension,
>> mutability, additional fields) have collapsed to their more restrictive
>> form; while some people will be disappointed because it doesn't solve
>> the worst of their boilerplate problems, our conclusion is: records are
>> a powerful feature, but they're not necessarily the delivery vehicle for
>> easing all the (often self-inflicted) pain of JavaBeans. We can
>> continue to explore relief for these situations too as separate
>> features, but trying to be all things to all classes has delayed the
>> records train long enough, and I'm convince they're separate problems
>> that want separate solutions. Time to let the records train roll.
>>
>> I've also combined the information on sealed types in this document, as
>> the two are so tightly related.
>>
>> Comments welcome.
>>
>>
>> --
>> Kevin Bourrillion | Java Librarian | Google, Inc. | [email protected]
>> <mailto:[email protected]>