2
MyClass e = new MyClass();

List<Object> ok = new ArrayList<Object>();
List<? extends Object> ko = new ArrayList<Object>();

ok.add(e);
ko.add(e); // doesn't compile

なぜコンパイルされないのですか?...MyClassのサブクラスですObject

詳細については、次のメッセージが表示されます。

The method add(capture#1-of ? extends Object) in the type List<capture#1-of ? extends Object> is not applicable for the arguments (MyClass)
4

2 に答える 2

7

これがあなたの問題です:

List<? extends Object>

これは、「オブジェクトを拡張するタイプTのリストですが、Tが何であるかは関係ありません」という意味です。

したがって、これは有効です。

List<? extends Object> ko = new ArrayList<Banana>();

...しかし、あなたは望まないでしょう:

ko.add(e);

その時点でコンパイルしますか?はMyClassではないからBananaです。

詳細については、JavaジェネリックFAQを参照しください。

于 2012-12-11T17:11:50.897 に答える
1

Josh Block は、Effective Javaで、 PECSについて教えてくれます: Producer = extends, Consumer = super.

コンシューマーkoとして使用しているため(オブジェクトを追加します)、次のように宣言する必要があります。

List<? super Object> ko = new ArrayList<Object>();

おそらく、概念のより良い説明は次のとおりです。

List<? super MyClass> ko = new ArrayList<Object>();

MyClass オブジェクトは、型が MyClass または任意のスーパー タイプである変数にのみ割り当てることができるのと同じように考えることができます。MyClass オブジェクトは、型が MyClass または任意のスーパー タイプである List にのみ追加できます。 .

あなたの例に戻ると、List<? extends Object> koこれも受け入れるため、正しい型宣言になることはできません。

List<? extends Object> ko = new ArrayList<String>();

のジェネリック型に基づいて、コンパイラは実際のList が MyClass のインスタンスを受け入れるkoことを確認できないことがわかります。

于 2012-12-11T18:30:06.537 に答える