[records] customized accessor returning subtype

Alex Buckley alex.buckley at oracle.com
Tue Dec 10 00:36:40 UTC 2019


I'm glad this was asked and answered during CSR, but I think Dmitry is 
clear about WHAT the spec says. I believe he is asking WHY an explicit 
accessor's return type must be identical to the component's type.

At the heart of the matter is the fact that a Number-typed component 
implies a Number-typed field. Code in an accessor with an Integer return 
type would have to downcast the field often, or at least sometimes. 
Everything about that accessor makes it harder to understand the state 
of the record *which was meant to be plain from the Number component*. 
Does the "true" state involve a Number or an Integer, and does it depend 
on other conditions, and when, and why? A covariant override is for when 
a subclass adds specialization, but there's no specialization to be 
gained within a record.

Alex

On 12/9/2019 4:04 PM, Joe Darcy wrote:
> FYI, this issue was raised in the CSR review:
> 
>> In "An implicitly declared public accessor method with the same name 
>> as the record component, whose return type is the declared type of the 
>> record component, unless a public method with the same signature is 
>> explicitly declared in the body of the declaration of R."
>>
>> does that imply a "covariant override" accessor can be explicitly 
>> defined as the signature does not include the return type? For example 
>> if the component had a type of Object and the user defined an 
>> accesssor method with a type of String? Would a bridge method need to 
>> be defined? Should the return type be constrained to match too?
>>
> 
> https://bugs.openjdk.java.net/browse/JDK-8233433?focusedCommentId=14302123&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14302123 
> 
> 
> and replied to
> 
>> This is a very good question. I've actually changed the description of 
>> accessor methods and constructor methods to make this clearer (I 
>> hope). In essence there is a two stage process. For accessor methods: 
>> If you have the name of a component and an empty formal parameter 
>> list, then you are considered to be an accessor method for the 
>> component. We then ask additional criteria of you - it's a 
>> compile-time error if you don't satisfy them! This includes having a 
>> return type that is identical to the derived type of the record 
>> component, being |public|, etc. It's essentially the same for 
>> constructors: a record component list essentially derives a canonical 
>> constructor signature. If you are a constructor that is 
>> override-equivalent, then you are a canonical constructor. We then ask 
>> additional criteria of you, being |public|, not being generic, etc.
>>
>> These definitions clear up a lot of corner cases, and more importantly 
>> lead to better error messages. (In your particular example, the 
>> |String| returning method would /not/ be an accessor for the |Object| 
>> component, so one would be implicitly declared for you, and then you'd 
>> get an error as we'd have two overloads with identical signatures).
>>
> https://bugs.openjdk.java.net/browse/JDK-8233433?focusedCommentId=14302457&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14302457 
> 
> 
> Cheers,
> 
> -Joe
> 
> On 12/9/2019 11:09 AM, Dmitry Bessonov wrote:
>> Is there any reason for not allowing a customized accessor to return 
>> rc subtype:
>>
>> record R(Number number) {
>>      public Integer number() {
>>          return 42;
>>      }
>> }
>>
>> Error: java: invalid accessor method in record R
>>    (return type of accessor method number() is not compatible with 
>> type of record component number)
>>
>>
>> dmitry
>>


More information about the amber-dev mailing list