> From: "John Rose" <john.r.r...@oracle.com>
> To: "daniel smith" <daniel.sm...@oracle.com>
> Cc: "valhalla-spec-experts" <valhalla-spec-experts@openjdk.java.net>
> Sent: Wednesday, February 9, 2022 7:32:07 PM
> Subject: Re: EG meeting, 2022-02-09 [SoV-3: constructor questions]

> On 8 Feb 2022, at 19:04, Dan Smith wrote:

>> "SoV-3: constructor questions": Dan asked about validation for <init> and 
>> <new>
>> methods. Answer: JVM doesn't care about <init> methods in abstract classes, 
>> the
>> rules about <new> methods still uncertain.
> On the question of JVM validation of <new> methods, I’m in favor of as few 
> rules
> as possible, ideally treating <new> as just another name. It’s super-power is
> not in its restrictions but in its conventionality: It’s the obvious choice 
> for
> constructor factory methods. But it is not necessarily limited to that use.

> Maximal limitation would be that a <new> method can only occur as the
> translation of a value-class constructor. Any evidence in the classfile that 
> it
> was not such a translation would be grounds for failing a validation check.
> We’d make as many such rules as we can think of.

> Arguments against:

>    * Having a special method identifier in the JVMs without other restrictions
>     would be a new thing, and hence suspicious.
>    * Limiting the use of <new> as much as possible makes it clear, to higher 
> layers
>    of the code (javac and reflection) what is going on in the class file, as a
>     “reflection” of the source file.
>    * Reflection of an irregular (non-source-conforming) <new> method has to be
>     messy. (Is it really a constructor? Or is it just a method named <new> ?)

> Arguments in favor:

>    * It is a new thing in the JVM for any descriptor to be constrained to 
> mention
>    the same name as is the name of the constant pool item referred to by
>     ClassFile.this_class item (JVMS 4.1). (It is suspicious.)
>    * A maximal limitation would break hidden classes. (They must sometimes 
> return a
>    supertype from their factories, since the HC is not always name-able in a
>     descriptor. HCs only work because the previous point.)
>    * A limitation might preclude a perhaps-desirable future translation 
> strategy
>    that used <new> factories uniformly to translate new source code 
> expressions
>     (identity or value objects, uniformly).
>    * A limitation could remove a natural translation strategy for “canonical
>    factory methods” in non-concrete types. This is a hypothetical language 
> feature
>    for Java or some other language. (E.g., new List(a,b,c) instead of
>    List.of(a,b,c) , removing the need of the user to remember whether the 
> word was
>     of or make or build or some other designer choice.)
>    * Most any limitation would preclude ad hoc use of <new> factories by
>    translation strategies of other languages, such as Scala and Clojure, which
>    surely have their own uses of JVM object life cycles. We want to be 
> friendly to
>     non-Java languages.

> Compromise positions:

>    * Require a <new> method to be ACC_STATIC but allow for any purpose (i.e., 
> any
>     access and any descriptor).
>    * Require a <new> method to return either the class named by this_class or 
> some
>     super type (TBD how this should be checked).

> I would prefer the first compromise: It’s static but otherwise the JVM asks no
> questions.

> Regarding reflection, I think it would be OK to surface all of the <new> 
> methods
> (of whatever signature) on the getConstructors list, even if they return
> “something odd”. Alternatively, to prevent a sharp edge we could have a new
> list Class::getFactories , and copy (not move) entries from that list onto
> getConstructors exactly when the return type matches the enclosing class. That
> is a more natural move for reflection (which operates on runtime types) than
> for class file structuring (which is more static).

> The reason I prefer to require static marking is that it would prevent the 
> funny
> name from appearing on the list of regular methods, via reflection.

I agree with static being the only requirement for the VM side. 

For reflection,i prefer the first alternative, surface the <new> method 
whatever the return type given that the return type is a declared type, not a 
runtime class. 
Dynamically typed languages like Groovy or JRuby may want to declare that the 
return type of <new> is java.lang.Object (it's the default type if no type is 
provided in Groovy), 
if reflection filter out those methods, it will be bad for the interropt 
between Java and those dynamically typed languages. 

Rémi 

Reply via email to