> > I don't understand the point of this restriction.  Since
> > Ljava/lang/Object; is acceptable (and has to be), I can use a `<new>`
> > method to return *any* class but the caller will need to downcast to
> > use it.
>
> I think the reason we might have some sort of restriction is if we intend for 
> a language or reflection API to be able to rely on these methods having some 
> consistent properties (imagine them being surfaced with 
> java.lang.reflect.Constructor, for example). So think of the restriction as a 
> placeholder ("we may have some sort of restriction on the return type, TBD"). 
> We still need to do some work to figure out the precise requirements, if any.
>

A constructor has the invariant that if it returns successfully, the
return value is an instance of the declaring class.  A <new> factory
method doesn't - and we've said above can't due to hidden classes -
have that invariant.

With a class like the follow, I know that regardless of what
parameters I give the ctor, I'm going to get an instance of the
declaring class:

class Example {
  public Example(int i) {
    // no matter what code, will have an example on stack after the
call or an exception
  }
}

But that's not true with value classes:

value class StangeNew {
  <new>:(I)Ljava/lang/Object; // descriptor as Javac won't generate this
    switch(i) {
    case 0: return "Foo";
    case 1: aconst_init QStrangeNew;
   case 2: ......
 }
}

As you said above, we've looked at this a number of times and each
time kind of let the discussion trickle away as there isn't a good
answer here.  We should be careful to avoid well intentioned
restrictions that don't match the real behaviour as they open doors
for attackers to slip past our (and users) assumptions.

--Dan

Reply via email to