Method/Constructor references.
Dan Smith
daniel.smith at oracle.com
Tue Feb 19 15:47:27 PST 2013
Thanks for the comments. They have helped to significantly improve 15.28.
On Feb 16, 2013, at 11:55 AM, Srikanth S Adayapalam <srikanth_sankaran at in.ibm.com> wrote:
> (1) 0.6.1, 15.28 says:
>
> "It is a compile-time error if the ClassType of a constructor reference denotes a class that is an enum type or that is abstract. "
>
> While JLS7 15.9 in addition says:
>
> "It is a compile-time error if any of the type arguments used in a class instance
> creation expression are wildcard type arguments (§4.5.1)."
>
> So is the less restrictive version with constructor references intentional ? I don't see anything in
> the design/motivation section regarding this to determine if it is.
>
> I would like to use one definition of what can be instantiated unless the relaxation is deliberate.
>
> So, should the following program compile ?
>
> // ---
> interface I {
> X<?> zoo(int x, String p);
> }
> public class X<T> {
> X(int x, String p) {}
> I i = X<? extends String>::new; // will compile
> X<?> x = new X<? extends String>(); // will not compile.
> }
>
> I don't see a type safety issue here since the parameterization would have pass bounds check, only a consistency issue.
Good catch. This is just something I missed when scanning through 15.9 for errors.
I've added a restriction on type arguments to Part C, 15.28. Wildcards are now prohibited from constructor references.
> (2) And since the production for ClassType (despite the name) cannot prune type variables and
> annotation types, should these also be called out as error scenarios ?
My intent is for the ClassType production to have a semantic meaning along with the syntax: it only applies to names of actual classes.
Looking at other usages of "ClassType" and "InterfaceType", though, as in 8.1.4 and 8.1.5, it seems to typically be accompanied by a restriction like "The ClassType must name an accessible (§6.6) class type, or a compile-time error occurs." I'll follow suit here.
> (3) Should the (obvious) point about primary evaluating to base type being a forbidden scenario
> be mentioned ?
I think you mean something like "1::m". That's covered in a roundabout way by Part E -- 15.28.1 says if 15.12.1 defines an error, then a candidate method is not applicable (and so no applicable methods would be found, and that would be an error).
But I think it's a lot more clear to state the restriction explicitly, so I will do so. I also see some restrictions from 15.12.1 on 'super' invocations (as modified by Part H) that deserve stating explicitly here, too.
> (4) "The immediately enclosing instance of an inner class instance (15.9.2) must be provided for a constructor reference by a lexically enclosing instance of this (8.1.3). "
> Is this restrictive ? Can this be supplied at method invocation time or even via a primary from ? Implementable != useful and
> I don't have an assessment as to how useful practically it would be though. Again this is a consistency issue: the call to
> new Inner() can occur outside of the enclosing class in an entirely unrelated class as long as there an enclosing instance is
> available and the types are visible.
I can think of three plausible ways to get an enclosing instance for an inner class constructor reference. Do you have one of these in mind?:
- There's a compatible enclosing 'this' from point of the constructor reference. Such a scenario is supported, and is what the above sentence is meant to describe.
- The constructor reference syntax provides the value, analogous to 'OuterObject.new Foo()'. We have no syntax for this scenario, and decided it wasn't worth adding syntactic complexity in order to support.
- The function descriptor has an extra parameter so that the _invoker_ of the reference can provide an enclosing instance. This scenario was discussed in one of the surveys from this summer and ultimately dismissed. (Again, too much complexity for a marginal benefit.)
—Dan
More information about the lambda-spec-experts
mailing list