15.28.1 needs some polish ?
Dan Smith
daniel.smith at oracle.com
Tue Feb 19 16:13:59 PST 2013
On Feb 17, 2013, at 5:06 AM, Srikanth S Adayapalam <srikanth_sankaran at in.ibm.com> wrote:
> Hello !
>
> (1) 0.6.1, 15.28.1 reads:
>
> -----------------------
> Given a function descriptor with parameter types P1..Pn, the compile-time declaration for a method reference is determined as follows.
>
> If the method reference is qualified by a ReferenceType, two searches for a most-specific applicable method are performed, following the process outlined in 15.12.2. Each search may produce a method or, in the case of an error as specified in 15.12.2, no result.
> First, the reference is treated as if it were an invocation of a method named by Identifier with argument expressions of types P1..Pn; the type to search is the ReferenceType; the type arguments, if any, are given by the method reference.
>
> Second, if P1..Pn is not empty and P1 is a subtype of ReferenceType, the reference is treated as if it were an invocation of a method named by Identifier with argument expressions of types P2..Pn. If the ReferenceType is a raw type, and there exists a parameterization of this type, G, that is a supertype of P1, the type to search is G; otherwise, the type to search is the ReferenceType. Again, the type arguments, if any, are given by the method reference.
>
> If both of these searches match a method, the reference is considered ambiguous.
>
> Otherwise, if the first search matches an instance method or the second search matches a static method, no method is chosen.
>
> Otherwise, if one of the searches matches a method, that is the compile-time declaration.
> ----------------------------
>
> The first mention of static occurs in the penultimate sentence of the quoted text: Does that mean the following program
> should be declared ambiguous ? (8b74 compiles this fine, but at run time there is an NPE) - There is no real ambiguity here.
>
> // ----
> interface I {
> void zoo(Y y, String s);
> }
>
> class Y {
> void zoo(String s) {
> System.out.println("Y.zoo(String)");
> }
> void zoo(Y y, String s) {
> System.out.println("Y.zoo(Y, String)");
> }
> }
>
>
> public class X {
> public static void main(String[] args) {
> I i = Y::zoo;
> i.zoo(null, null);
> }
> }
> // -----------
>
> I think this calls for a reordering of clauses and perhaps some rewording ?
> The sentence "Otherwise, if the first search matches an instance method or
> the second search matches a static method, no method is chosen." is a bit
> vague ? i.e does this mean "No method is chosen as the compile declaration
> of the method reference" or that "these matches are eliminated from further
> reckoning ?"
>
> Also the sentence "If both of these searches match a method, the reference
> is considered ambiguous." preceding the first utterance of 'static' would
> render the program above illegal.
>
> Or reword the passage "First, the reference is treated as if it were an
> invocation of a method" to "First, the reference is treated as if it were an
> invocation of a _static_ method" and likewise massage the second part too ?
This is an intentional design choice, although I think it's not quite right.
The goal is to mimic the behavior of 15.12: a "static" method invocation can match an instance method, and it's only after a most-specific applicable method is chosen that an error occurs (per 15.12.3). Generalizing, the search for a method is not supposed to take 'static'-ness into account. (If anybody feels like this hasn't been sufficiently discussed, though, I acknowledge that this is a bit of a leap and we can debate it more...)
So your example should be an error.
In addition, 'static'-ness shouldn't affect resolution of an enclosing method invocation (e.g., 'overloadedMethod(Foo::m)'), any more than type arguments do (e.g., 'overloadedMethod(Foo<Bar>::m)'), so the check should wait to happen until after compatibility has been established. So I've removed the sentence in question entirely, and added a similar restriction to the bulleted list that starts with "A method or constructor reference may be illegal even if it is compatible with its expected type".
—Dan
More information about the lambda-spec-experts
mailing list