When trying to compile the expression Comparator.comparing(String::toLowerCase)
, the Java Compiler returns an error. See the following question for more information:
Why Comparator.comparing doesn't work with String::toLowerCase method reference?
I have tried to reduce the problem as much as possible. In particular, I have removed almost all dependencies to other classes. The main method contains two method invocations. The first statement compiles without errors, whereas the second statement produces an error.
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 shouldn't be applicable in this context, due to the mismatch in the number of parameters. I have taken a look at the JLS8 (15.13). However, it was no help, because the rules for method references are quite complex.
Q: Why is there a compilation error for the second case? Should there really be a compilation error according to the JLS? According to some comments on the other question, there is no compilation error in Netbeans.
For reference, I am using the JDK8 version 1.8.0-b132. If a compile the program on the command line, the compiler shows 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>invoke(Fun<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