15.28.1 needs some polish ?
Ali Ebrahimi
ali.ebrahimi1781 at gmail.com
Sun Feb 24 02:07:00 PST 2013
Hi Dan,
with current spec, resolving method references in overloaded generic method
contexts fails and gives ambiguity error.
Consider two scenario:
interface Sam1<X> {
void m(X x);
}
interface Sam2<X,Y> {
void m(X x,Y y);
}
1) scenario that we have two target types with arity n and n+1 and one
method
class Test {
void m(String s) { }
static <U> U u(Sam1<U> s) { return null; }
static <U,T> U u(Sam2<U,T> s) { return null; }
static void testUnbound() {
Test s = u(Test::m);
}
2) scenario that we have two methods with arity n and n+1 and one target
type with arity n+1
class Test {
void m() { }
void m(String s) { }
static <U> U u(Sam1<U> s) { return null; }
static void testUnbound() {
Test s = u(Test::m);
}
Best Regards,
Ali Ebrahimi
On Wed, Feb 20, 2013 at 4:43 AM, Dan Smith <daniel.smith at oracle.com> wrote:
> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20130224/d79a2ce8/attachment.html
More information about the mlvm-dev
mailing list