У меня проблема с выражением типа Java. Я использую JAVAC 1.8.0_121, и следующий код компилируется с Eclipse, СЕС, но не с JAVACРазличные результаты вывода типа с помощью javac и ecj
import java.util.function.Function;
public class Playbook {
static class A {
}
static class B {
}
static class P<T> {
}
static class V<T> {
static <T, U> V<U> m(P<T> src, Function<? super T, ? extends U> f, Function<? super U, ? extends T> g) {
return null;
}
void b(final P<T> other) {
}
}
public void bindTimeString1(P<A> p1, P<B> p2) {
V.m(p2, s -> new A(), t -> new B()).b(p1);
}
}
Компиляция это с результатами JAVAC в следующей ошибки:
[ERROR] Playbook.java:[31,47] incompatible types: main.java.Playbook.P<main.java.Playbook.A> cannot be converted to main.java.Playbook.P<java.lang.Object>
Без второго параметра g
из m
код компилируется без проблем:
import java.util.function.Function;
public class Playbook {
static class A {
}
static class B {
}
static class P<T> {
}
static class V<T> {
static <T, U> V<U> m(P<T> src, Function<? super T, ? extends U> f) {
return null;
}
void b(P<T> other) {
}
}
public void bindTimeString2(P<A> p1, P<B> p2) {
V.m(p2, s -> new A()).b(p1);
}
}
Я не понимаю, почему это не удается в первую очередь. Из кода, компилятор может сделать вывод, что:
- е возвращает то, что расширяет U.
- г принимает то, что является базовым классом U.
- Из тела ничего г Более можно сделать вывод о U.
- Из корпуса f, он знает, что он возвращает A, поэтому A <: U должен быть правдой.
- Var.b не накладывает никаких ограничений больше на U, поэтому U может быть любого типа, который удовлетворяет <: U. В этом случае, это оставляет нас с А или объект в качестве потенциальных кандидатов на U.
кажется, что компилятор выбирает объект, когда g
присутствует, но когда m
унарна, хотя g
не добавляет ничего о U.
Я также запутаться, если это вопрос в СЕС или JAVAC, как СЕС принимает кода и javac нет. Только один из них может быть правильным.