このコード:
List<? extends Reader> weirdList;
weirdList.add(new BufferedReader(null));
のコンパイルエラーがあります
List 型のメソッド add(capture#1-of ? extends Reader) は、引数 (BufferedReader) には適用されません。
なんで?BufferedReader はリーダーを拡張するのに、なぜ「一致」しないのでしょうか?
List<? extends Reader> weirdList
List
は、任意のタイプのを格納する任意のタイプへの参照を保持できますReader
。だから、それは可能です
List<? extends Reader> weirdList1 = new ArrayList<BufferedReader>();
List<? extends Reader> weirdList2 = new ArrayList<FileReader>();
Java で追加できる場合は、sのみを格納する必要があるため、発生するとは想定されていない (参照型は同じ) に追加するBufferedReader
必要weirdList1
もあります。BufferedReader
weirdList2
weirdList2
FileReader
コンパイラがを確認すると、それが または extends である任意の<? extends Reader>
型であると想定します。など、と互換性のないものである可能性があります。したがって、クラス定義のジェネリック型が などのメソッドのパラメーターに表示され、インスタンスの型が のようなものである場合、コンパイラは型の安全性の理由からそれを許可しない必要があります。この例では である可能性があるため、ここに a を追加することはできません。Reader
BufferedReader
StringReader
add
<? extends Something>
List<StringReader>
BufferedReader
あなたが与えた変数について:
List<? extends Reader> weirdList;
次の割り当てはすべて有効です。
weirdList = new ArrayList<Reader>();
weirdList = new ArrayList<FileReader>();
weirdList = new ArrayList<BufferedReader>();
weirdList = new ArrayList<InputStreamReader>();
うまくいけば、これでコンパイルエラーが説明されます。weirdList
type の値を保持している場合は意味がありますが、 typeArrayList<BufferedReader>
の値には意味がありませんArrayList<FileReader>
。タイプの変数はList<? extends Reader>
いずれかのタイプ (およびそれ以上のタイプ) の値を保持できるため、Java はそれをエラーと呼びます。
Java のジェネリックは理解しにくいものです。List<? extends Reader>
型は、さまざまな型を受け入れることができるように、メソッドの割り当てまたはパラメーター型に最も役立つと考えることができます。List<Reader>
「通常の使用」の場合は、またはのような「裸の」ジェネリックを使用したほうがよいでしょうList<BufferedReader>
。