7

先日、他の人のコードをレビューしていて、懸念を引き起こす行に出くわしました。簡単にするために、一般的なクラス A と抽象クラス B があるとします。次のインスタンス化は許可されていますか。

Object obj = new A<? extends B>();

私は個人的に、上記のようなインスタンス化を見たことがありません。

A<? extends B> obj = null;

確かに保持されます。メソッド パラメーターを宣言するためにジェネリックスで常にワイルドカードを使用してきたので、経験がないだけかもしれません。

4

1 に答える 1

4

実際new A<? extends B>()にはコンパイルされません。Java 5 以降、一貫して違法でした。

しかし、あなたの元の例はのようなものだったと思いますnew A<X<? extends B>>()。後者は、最近のバージョンの Java では有効です。

アイデアは、オブジェクトをインスタンス化するときに、型パラメーターの値をワイルドカード以外の型にすることができるということです。? extends Bはワイルドカード タイプであるため、許可されません。ただし、コンポーネントとしてワイルドカード型がありますX<? extends B>、ワイルドカード型ではありません。したがって、合法的に呼び出すことができます。new A<X<? extends B>>()

このように考えれば、ルールは理にかなっています。最終的には、ワイルドカード型のようなフィールドまたは変数の宣言され? extends Bた型にすることはできないという、より基本的な規則の副産物です。が次のように定義されている場合A

class A<T> {
    T value;
}

その場合、仮説はtype の宣言されnew A<? extends B>().valueたフィールドになります。それは違法であるため、インスタンス化も違法です。しかし、その問題はありません。 ? extends Bnew A<X<? extends B>>()

于 2012-10-06T16:50:11.003 に答える