> "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.
I'm in agreement here. It's a newly legal name but doesn't impose additional constraints that the JVM needs to check. It's fine (and probably good) if the language is more principled about when / why it generates the new names (ie. only for Value initializers) so there's a clear convention .... > 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. [reordered from the end] > 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. This is a reasonable requirement, easily checked statically from just the present classfile, and one we can easily lift if a future use case requires it. > > 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). > I like this Class::getFactories and copy to getConstructors move. It's clear about what's happening and avoids the sharp edge of a "Constructor" for Class X returning an instance that isn't an "X". For classes generated by javac, the convention that their "<new>" methods return type exactly matches the enclosing class will allow most programmers not to think about it when writing reflective code - the obvious X.class.getConstructor() will work in all cases. And the strange use cases are easily reachable through the new getFactories method. I like it. --Dan