When I try to compile this code
import java.util.Optional;
public class GenericTest {
public static void main(String[] args) {
Optional.empty().map(o -> getStringClass(o)).orElse(String.class);
}
static Class<?> getStringClass(Object arg) {
return String.class;
}
}
javac will fail with the following error:
GenericTest.java:6: error: method orElse in class Optional cannot be applied to given types; Optional.empty().map(o -> getStringClass(o)).orElse(String.class); ^ required: Class<CAP#1> found: Class<String> reason: argument mismatch; Class<String> cannot be converted to Class<CAP#1> where T is a type-variable: T extends Object declared in class Optional where CAP#1 is a fresh type-variable: CAP#1 extends Object from capture of ? 1 error
But if I use a method reference instead, javac will compile the code just fine:
import java.util.Optional;
public class GenericTest {
public static void main(String[] args) {
Optional.empty().map(GenericTest::getStringClass).orElse(String.class);
}
static Class<?> getStringClass(Object arg) {
return String.class;
}
}
Why does it make a difference if I use a method reference or a lambda expression?
According to my understanding, both the method reference and the lambda have the type Function<Object,Class<?>>
, so I don't see the difference here.
The eclipse java compiler (ecj) won't compile both versions by the way.