2

私はこのC#の質問を見て、Javaで同様のことが起こるのではないかと考えました。それは、

class A<T> {
    A(Integer o) {...}
    A(T o) {...}
}

呼び出し

new A<Integer>(43);

あいまいで、解決する方法がわかりません。ありますか?

4

3 に答える 3

3

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);
于 2011-04-17T09:02:05.333 に答える
2

確かに、それはあいまいなので、試してみてもコンパイルされませんnew A<Integer>(new Integer(0))

于 2011-04-17T08:36:14.813 に答える
2

はい、パラメータ化された型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番目のコンストラクターよりも具体的ではありませんか?finalIntegerIntegerT

finalサブタイピング関係では、番号は考慮されません。実際には1日から削除することは可能であり、Javaは、削除してもバイナリ互換性が損なわれないと指定してfinalいます。Integerfinal

于 2011-04-17T17:02:50.440 に答える