RFR:JDK-8198749 Translation of value constructors in classic constructor notation

John Rose john.r.rose at oracle.com
Thu Jul 12 17:54:09 UTC 2018


On Jul 12, 2018, at 12:45 AM, Remi Forax <forax at univ-mlv.fr> wrote:
> 
> I will prefer not too allow (value) class constructor to return a value, it's what <make> factory method are for.
> 
> I think it's better to:
> - allow <make> factory method for value and reference that returns a value/reference of any type.
> - have value class constructor automatically translated to <make> factory method by the compiler.
> - make <init> constructor and <make> factory mutually exclusive.

All that is reasonable to me.  (Scoping is after LW1 of course.)

So you vote for making a clean break from <init> to <make>.
That's probably the right thing to do; I can't think of a strong reason
to cleverly recycle <init> (with a new method type) to denote <make>.

My point about an early value-return makes sense for <make> but
not <init>, since <init> is required to update its given L[0] argument
in place.

In the language, I'm speculating that there could be a place for
a kind of source-level constructor which is really a <make> method
not an <init> method.  That kind of constructor could logically
be given the capability to do an early value-return, since it's
really a factory method.

Such a constructor, if we decided to create it, would need a
method type signature which allowed the value-return.
Value types always have this, while currently object types
never have this signature.  So there's a notation problem
to solve, which I don't have much opinion on.  Maybe you
mark a constructor using the keyword "factory" in an object
class, and constructors in value classes are always factories?

It's almost possible to make <init> and <make> mutually
exclusive, except for non-final objects.  In that case, the
object class has API points for creators, which should
be named <make>, and API points for subclasses, which
still need to be named <init>.

In a case like that, the <make> method, if it is derived from
a non-factory constructor, consists of the following code:

   ACC_STATIC <make> (Arg…)ObjCls {
     new ObjCls
     dup
     push Arg...
     invokespecial ObjCls.<init>(Arg…)V
     areturn
   }

The <init> method can be downgraded from ACC_PUBLIC
to ACC_PROTECTED, and the verifier can be tightened
up to exclude uses of <init> which are now covered by
<make>.

Result:  A new convention for canonical factory methods
for all types (object, value, interface), replacing and extending
the translation strategy that used <init> for "new ObjClass(arg…)".

— John


More information about the valhalla-dev mailing list