1

数日前、私は単純な Java プログラムを書いていましたが、このコードが機能しないことを発見しました (コンパイル時にエラーが発生します)。

ArrayList<Document> docs = new ArrayList<Book>();

ここで、Document はインターフェイスで、Book は Document を実装します。

Javaの継承がジェネリックで機能しないのはなぜですか? そのコードを機能させたい場合は、次のようにワイルドカードを使用する必要があります。

ArrayList<? extends Document> docs = new ArrayList<Book>();

この理由は何だろう?と思いました。Document の ArrayList が必要で、Book も Document であることがわかっている場合、Book の ArrayList を Document の ArrayList として使用できないのはなぜですか?

4

2 に答える 2

7

次の例を検討してください。

ArrayList<Book>books = new ArrayList<Book>();
ArrayList<Document> docs = new ArrayList<Book>();
docs.add(new Document());
Book book = books.get(0); //Oops, now we have a variable of type book, referring to a Document that is not a book. Not good.

この問題に関するより概念的な背景資料が必要な場合は、共分散と反分散を読んでください。

于 2013-06-16T09:06:37.977 に答える
5

の型が(U = VList<U>でない限り) のサブタイプになれないからです。List<V>

ここに画像の説明を入力

たとえば、それList<Integer>が のサブタイプであることを認める場合List<Number>。次のように書くことができます:

void addPi(List<Number> l) {
 l.add(3.14);
}

List<Integer> l = new LinkedList<>();
addPi(l);

ここで何が問題ですか?

于 2013-06-16T09:06:33.777 に答える