Java – invalid method reference for overloaded methods with different arities

Try compiling the expression comparator When comparing (string:: tolower case), the java compiler returns an error For more information, see the following questions:

Why Comparator. comparing doesn’t work with String::toLowerCase method reference?

I tried to minimize the problem In particular, I have removed almost all dependencies to other classes The main method contains two method calls The first statement compiles without errors, while the second statement generates errors

interface Fun<T,R> { R apply(T t); }

public final class Foo {
    public static void main(String... args) {
        invoke(Foo::bar); // OK
        invoke(Foo::baz); // ERROR
    }
    private static <T,U> void invoke(Fun<T,U> f) { }
    private String bar() { return null; }
    private String baz() { return null; }
    private String baz(Integer i,Integer j) { return null; }
}

This is strange because the second Baz method should not be suitable for this situation because the number of parameters does not match I've seen jls8 (15.13) However, it doesn't help because the rules of method reference are very complex

Q: why do compile errors occur in the second case? Will compilation errors really occur according to JLS? According to some comments on another issue, there are no compilation errors in NetBeans

For reference, I use JDK 8 version 1.8 0-b132. If you compile the program on the command line, the compiler displays the following error message:

$/opt/jdk8/bin/javac Foo.java
Foo.java:6: error: incompatible types: cannot infer type-variable(s) T,U
        invoke(Foo::baz); // ERROR
              ^
    (argument mismatch; invalid method reference
      no suitable method found for baz(Object)
          method Foo.baz() is not applicable
            (actual and formal argument lists differ in length)
          method Foo.baz(Integer,Integer) is not applicable
            (actual and formal argument lists differ in length))
  where T,U are type-variables:
    T extends Object declared in method <T,U>invoke(Fun<T,U>)
    U extends Object declared in method <T,U>)
Foo.java:6: error: invalid method reference
        invoke(Foo::baz); // ERROR
               ^
  non-static method baz() cannot be referenced from a static context
2 errors

Solution

Jls8 (15.13) is confusing, but it does show examples similar to yours, which shows that their ambiguity in search can not be solved

For your example, IntelliJ says invoke (foo:: Baz); It's a circular inference. I think it's more related to the inference type of the call and the combination of foo:: Baz

This can be solved by typing the calling function, similar to JSL (example 15.13.1)

Foo < foo, string > Call (foo:: Buzz); – Equivalent to, I want to use Foo's void method to return a string aka string baz()

interface Fun<T,R> { R apply(T t); }
interface Fun2<T,U,R> { R apply(T t,U u); }

public final class Foo {
    public static void main(String... args) {
        invoke(Foo::bar); // OK
        Foo.<Foo,String>invoke(Foo::baz); // NO ERROR
        Fun2<Foo,Integer,String> f2 = Foo::baz; // Overloaded method baz
    }
    private static <T,U> f) { }
    private String bar() { return null; }
    private String baz() { return null; }
    private String baz(Integer i) { return null; } 
}

I agree with you that Baz (integer I) is not a valid parameter. You can set it to static or instance from foo without calling it I think if the method overloads and it tries to infer the type, the search algorithm will exit Because it uses only one method signature

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>