Когда я пытаюсь скомпилировать этот код
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 завершится ошибкой со следующей ошибкой:
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
Но если вместо этого я использую ссылку на метод, javac скомпилирует кодпросто отлично:
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;
}
}
Почему это имеет значение, если я использую ссылку на метод или лямбда-выражение?
Насколько я понимаю, и ссылка на метод, и лямбда имеют типFunction<Object,Class<?>>
, поэтому я не вижу здесь никакой разницы.
Java-компилятор eclipse (ecj), кстати, не скомпилирует обе версии.