私はこのC#の質問を見て、Javaで同様のことが起こるのではないかと考えました。それは、
class A<T> {
A(Integer o) {...}
A(T o) {...}
}
呼び出し
new A<Integer>(43);
あいまいで、解決する方法がわかりません。ありますか?
私はこのC#の質問を見て、Javaで同様のことが起こるのではないかと考えました。それは、
class A<T> {
A(Integer o) {...}
A(T o) {...}
}
呼び出し
new A<Integer>(43);
あいまいで、解決する方法がわかりません。ありますか?
You can drop the generics during construction (and suppress a warning):
A<Integer> a = new A(42);
or, less preferably use reflection (where again you'd have to suppress warnings)
Constructor<A> c = A.class.getDeclaredConstructor(Integer.class);
A<Integer> a = c.newInstance(42);
確かに、それはあいまいなので、試してみてもコンパイルされませんnew A<Integer>(new Integer(0))
。
はい、パラメータ化された型JLS3#4.5.2のメンバーは、通常のクラス宣言(#8.4.8)で排除される競合に終わる可能性があります。この種の多くの例を思い付くのは非常に簡単です。
T
また、Javaでは、との間にサブタイピング関係がないため、この例のどちらのコンストラクターも他のコンストラクターよりも具体的ではありませんInteger
。参照はジェネリックとあいまいですも参照してください
メソッドのオーバーロードによってこの種のあいまいさが生じる場合、通常、個別のメソッド名を使用することを選択できます。ただし、コンストラクターの名前を変更することはできません。
その他のソフィストリー:
<T extends Integer>
、thenが実際T
にのサブタイプである場合Integer
、2番目のコンストラクターは1番目のコンストラクターよりも具体的であり、2番目のコンストラクターが選択されます。
実際、javacでは、これら2つのコンストラクターを共存させることはできません。現在のJava言語仕様には、それらを禁止するものはありませんが、バイトコードの制限により、javacはそれらを禁止します。Javaでの型消去とオーバーロードを参照してください:なぜこれが機能するのですか?
別のポイント:もし<T extends Integer>
、なので、TInteger
は、のサブタイプでなければならないので、2番目のコンストラクターも1番目のコンストラクターよりも具体的ではありませんか?final
Integer
Integer
T
final
サブタイピング関係では、番号は考慮されません。実際には1日から削除することは可能であり、Javaは、削除してもバイナリ互換性が損なわれないと指定してfinal
います。Integer
final