2013-04-02 11 views
5

このコード:(?1-のキャプチャ#リーダーを拡張)<? extends > Java構文

List<? extends Reader> weirdList; 
weirdList.add(new BufferedReader(null)); 

は、メソッドが追加

のコンパイルエラーを持っているタイプ リストには適用されません 引数(BufferedReader)

なぜですか? BufferedReaderはリーダーを拡張するので、なぜそれが "一致"ではないのですか?

+2

[Javaジェネリックスワイルドカード質問:リストの可能な複製(http://stackoverflow.com/questions/5495383/java-generics-wildcard-question-list-extends-a) – yshavit

+0

(FWIW、ここで何をしたいか'List <?extends Reader>'ではなく 'List 'です。) –

答えて

3

List<? extends Reader> weirdList; 

次の割り当てのすべてが有効です。

weirdList = new ArrayList<Reader>(); 
weirdList = new ArrayList<FileReader>(); 
weirdList = new ArrayList<BufferedReader>(); 
weirdList = new ArrayList<InputStreamReader>(); 

うまくいけば、これはあなたのコンパイルエラーについて説明します。 weirdListにタイプArrayList<BufferedReader>の値が入っていても、ArrayList<FileReader>の値には意味がありません。 List<? extends Reader>型の変数はいずれかの型の値を保持できるため、Javaではエラーが発生します。

Javaのジェネリックスは頭を悩ますことができません。 List<? extends Reader>型は、さまざまな型を受け入れることができるように、メソッドの代入やパラメータ型に最も役立つと考えることができます。 「通常使用」の場合は、List<Reader>List<BufferedReader>のような「ベア」ジェネリックの方が良いでしょう。

6

コンパイラは<? extends Reader>を見たとき、それはそれがあるかReaderを拡張任意の型である可能性があることを前提としています。それはBufferedReaderと互換性がないもの、例えばStringReaderです。したがって、クラス定義のジェネリック型がaddなどのメソッドのパラメータに現れ、インスタンスのタイプが<? extends Something>の場合、コンパイラは型の安全性の理由からそれを禁止する必要があります。この例では、となります。List<StringReader>となるので、ここにBufferedReaderを追加することはできません。

6

List<? extends Reader> weirdListは、いずれのタイプのReaderも格納する任意のタイプのListを参照することができます。だから、weirdList2を保存する必要があるために発生することが想定されていない(参照型が同じである)は、Javaを使用すると、weirdList1BufferedReaderを追加できるようになるならば、それはまた、あなたがweirdList2BufferedReaderを追加できるようにする必要があります

List<? extends Reader> weirdList1 = new ArrayList<BufferedReader>(); 
List<? extends Reader> weirdList2 = new ArrayList<FileReader>(); 

ことは可能ですのみFileReader秒。あなたが与えた変数については

関連する問題