1
私はJavaの型推論に問題があります。私ではなく、javacのjavacとecjで異なる型推論結果
次のエラーでjavacの結果でこれをコンパイルする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);
}
}
と、EclipseのECJでコンパイルしないのjavac 1.8.0_121、次のコードを使用しています:
[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);
}
}
なぜこれが最初に失敗するのかわかりません。コードから、コンパイラはそれを推測することができます。
- fはUを拡張し、何かを返す
- グラムは、より多く、約推測できるグラムのボディnothingからU.
- のベース・クラスである何かを受け入れますU.
- f体から、それはAを返すことを知っているので、A <:Uは真でなければなりません。これは
コンパイラがg
が存在するときにオブジェクトを選択したようだが、g
はU.
については何も追加しませんがm
は、単項のときECJは受け入れるとして、これはECJかのjavacで問題である場合、Aは、私も混乱していますコードとjavacはありません。それらのうちの1つだけが正しいことができます。