Javaのジェネリック:右である、のjavacまたはEclipseは、コンパイル?
-
19-09-2019 - |
質問
このメソッドを呼び出すます:
public static @Nonnull <TV, TG extends TV> Maybe<TV> something(final @Nonnull TG value) {
return new Maybe<TV>(value);
}
このような
public @Nonnull Maybe<Foo> visit() {
return Maybe.something(new BarExtendsFoo());
}
Eclipseでうまくコンパイルが、javacは、「互換性のないタイプ」の警告を与えます
found : BarExtendsFoo
必要な:はFoo
解決
javacのが正しい型を推論しなかった理由
私は、
を理解していません
しかし、あなたは、
public @Nonnull Maybe<Foo> visit() {
return Maybe.<Foo, BarExtendsFoo>something(new BarExtendsFoo());
}
他のヒント
のjavacとEclipseの間にいくつかの違いが明らかにあります。しかし、ここでの主なポイントは、javacのエラーが発光して正しいことです。最終的に、あなたのコードは危険であるかもしれない
ここで訪問()メソッドの書き換えです
public static <TV, TG extends TV> Maybe<TV> something(final TG value) {
return new Maybe<TV>(value);
}
public static class Foo { }
public static class BarExtendsFoo extends Foo { }
public Maybe<Foo> visit() {
Maybe<BarExtendsFoo> maybeBar = something(new BarExtendsFoo());
Maybe<Foo> maybeFoo = maybeBar; // <-- Compiler error here
return maybeFoo;
}
この書き換えは、あなたのコードと実質的に同じであるが、それは明示的には、
public static void bomb() {
Maybe<String> maybeString = new Maybe<String>("");
// Use casts to make the compiler OK the assignment
Maybe<Object> maybeObject = (Maybe<Object>) ((Object) maybeString);
maybeObject.set(new Integer(5));
String s = maybeString.get(); // Runtime error (classCastException):
// java.lang.Integer incompatible with
// java.lang.String
}
二つのコメントます:
A。あなたのコメントの1で述べたように、あなたがこの方法でやっているサブクラスTGに固有のものはないと、何かでTG型パラメータ()の署名が、全く必要ありません。
B。これに対する最も簡単なsoluionは、明示的に(通常は良い練習とにかくです)変数に新しく作成されたオブジェクトを割り当てることにより、使用しているタイプかを理解するために、コンパイラを手助けすることです。それは今あなたがメソッドを呼び出すしたいのですがどのようにコンパイラと人間の読者の両方に明確です。
public @Nonnull Maybe<Foo> visit() {
final Foo bar = new BarExtendsFoo();
return Maybe.something(bar);
}
所属していません StackOverflow