JAVAジェネリックでは、これが有効でないのはなぜですか:
List<?> l = new ArrayList()<?>;
これが有効であることを考慮すると:
public interface someList<?>{}
両方の無制限のワイルドカードがあります。私の考えでは、どちらも次と同等です。
List l = new ArrayList();
と
public interface someList {}
どこが間違っていますか?
List<?>
いずれかのタイプを意味します。プログラマーが型チェックの恩恵を受けるには、インスタンス化中にその1 つの型を提供する必要があると設計者が考えました。
完全な柔軟性が必要な場合List<?> l = new ArrayList<Object>()
は、行く方法です。
ワイルドカード?
は、はい、ジェネリックが必要ですが、どのタイプでも構いません。ジェネリックのないバリアントとは異なり、必要に応じて型チェックとコンパイラの警告が引き続き表示されます。
なぜなら、未知の型のArrayList
をインスタンス化できないからです。
rawタイプのをインスタンス化できますArrayList
。
new ArrayList();
ArrayList
または、オブジェクトまたは特定の既知のタイプをインスタンス化できます。
new ArrayList<Object>();
new ArrayList<String>();
これを行うだけです:
class CrazyBogusUnrelatedType { }
List<?> l = new ArrayList<CrazyBogusUnrelatedType>();
本当。これは 100% 正しく、100% タイプセーフです。これは、そこに任意のものを使用できることを示しています。それはまた、これを行うことの不条理を示しています。
私の考えでは、どちらも次と同等です。
遠く離れていません。それらは正反対です。
を使用List l
すると、何でも追加できます。ではList<?> l
、 以外には何も追加できませんnull
。したがって、基本的に、初期化で使用するリストList<?> l = new ArrayList()<?>;
はほとんど完全に役に立ちません。これは空であり、追加null
することしかできないため、含めることができるのはnull
要素だけです。
これは、ワイルドカードを使用した結果です。PECS (プロデューサーextends
、コンシューマーsuper
) ルールを思い出してください。extends
ここにはワイルドカードがあります (無制限のワイルドカードは、ほとんどの目的で と同じextends Object
です)。したがって、これはプロデューサーとしてのみ役立ちます。生成するものが何もないことを除いて、それは空です。では、なぜこれが欲しいのでしょうか?
ナンセンスなジェネリック型のオブジェクトを作成しようとするためです。オブジェクトが作成された場合、Java は量子世界をモデル化しないため、同時に多くの型であるとは限りません。ワイルドカード型は、型パラメーターが事前にわかっていないことを示しますが、値がある場合は具体的な型になります。
List l = new ArrayList();
後者は静的型オブジェクトの値のみを許可するため、これは同等ではありませんが、ジェネリックの助けを借りて、型を任意の参照型に制限できます。(ただし、この情報はコンパイル時にのみ存在します)