[records] A link between record component and a getter method

Brian Goetz brian.goetz at oracle.com
Wed Sep 25 17:11:38 UTC 2019


The basic principle behind records is that the user has given up the 
ability to decouple the API from the representation.  This benefits the 
user with a concise declaration, and it benefits clients by being able 
to reason about the existence and semantics of a fixed set of members 
(ctor, dtor, accessors, object methods.)  And clients are further 
divided into two buckets: human clients and frameworks.

If I read your query correctly, you're concerned primarily about the 
naming of the accessor methods.  And your reasoning goes something like 
this:

  - In other languages, we might want to use a different naming 
convention (for concreteness, let's call this getFoo()) for the accessors
  - If we reified the mapping from components to accessor methods, then 
framework clients could still do their job

First, let's note that the concision benefit is independent of 
record-ness for other languages, since languages can define their own 
rules about how a class is declared.  So the benefits of another 
language generating a record classfile exists for interop with Java 
users / Java code that knows about records.

Since we're telling Java users that a record's API is derived 
deterministically from its state description, I think having the 
latitude to rename accessors conflicts with that.  (However, there's 
nothing to stop you from generating _both_ a getFoo() and foo() methods, 
so that Java users will see the API they expect.)

The extent to which we validate the classfile at runtime is a separate 
consideration; we can choose to fail fast (at the cost of more VM 
complexity and startup cost), or treat it as "buggy compiler" and let 
things fail in reflection.  We have, so far, leaned towards the latter 
approach.



> JLS for records says that record component getter is named in the same
> way as the corresponding field, and this is completely fine for Java
> language. However it's unclear for me which approach is best for the
> JVMS. I see several options:
>
> - No direct link between record component and the corresponding getter
> method at all. A class is free to have an arbitrary named getter or
> provide no getter at all. Reflection API believes that there's a
> getter named after the record component and may fail for custom
> generated classes, but otherwisely these classes work fine.
> - Strict requirement that a class must contain a method named exactly
> like a record component and having no parameters and exactly the same
> return type as the record component type, otherwise the class
> verification fails.
> - Flexible link: a record component has a new required attribute like
> "Getter" which links an arbitrarily named method which has no
> parameters and exactly the same return type as the record component
> type.
>
> The latter option may be more friendly for JVM languages other than
> Java: they may also produce class files with the record components
> linking them to the getter names which are traditionally generated in
> given language for data classes or case classes (usually "getName" for
> "name" component, etc.). In this case both bytecode analysis tools and
> reflection-based frameworks could process Java records and non-Java
> data-classes/case-classes uniformly.
>
> What do you think?
>
> With best regards,
> Tagir Valeev.



More information about the amber-spec-experts mailing list