2011-09-24 11 views
5

私の質問は、Java 7には約ジェネリック医薬品は、我々はそのようなクラス階層があるとしている。ジェネリックスのワイルドカード: "?super T"は "?extends T"は動作しませんか?

interface Animal {}  
class Lion implements Animal {}  
class Butterfly implements Animal {} 

Java Generics Tutorial

にも、我々はクラスを持っているだけのように

class Cage<T> { 
    private List<T> arr = new ArrayList<>(); 
    public void add(T t) { 
     arr.add(t); 
    } 
    public T get() { 
     return arr.get(0); 
    } 
} 

そして、ここではコードですそのクラスを使用する:

public static void main(String[] args) { 
     Cage<? extends Animal> cage = new Cage<>(); 
     Animal a = cage.get(); //OK 
     cage.add(new Lion()); //Compile-time error 
     cage.add(new Butterfly()); //Compile-time error 
    } 

質問#1:

私はこれらの問題についてhereと読みましたが、単純にCage<?>のようでした。しかし、私はコンパイラに<? extends Animal>と言うので、タイプTCage<T>は動物型のいずれかのサブタイプになります。それではなぜコンパイル時にエラーが出るのですか?

質問#2:

私はすべてが正常に動作し、コンパイラが悪い何も言っていないCage<? super Animal> cage = ...代わりCage<? extends Animal> cage = ...のを指定した場合。なぜ上の例では失敗するのですか?

答えて

6

ケージは、の両方の種類の動物を保持できる必要があります。 「スーパー」は、ケージが保持できる必要があると言いますは動物のスーパークラスかもしれないので、動物のタイプ、そしておそらく他のものもあります。 、

Cage<? extends Animal> cage = new Cage<Lion>(); 

有効な文になりますが、明らかにライオンケージは蝶を保持しています:多分ちょうどライオンズは、例えば、のように - 「拡張」、それは動物の一部種類を保持できることを言います従って

cage.add(new Butterfly()); 

はコンパイルされません。 Cage<? extends Animal> - - いない今、それに割り当てられているオブジェクト(Cage<Lion>)。ここではJavaはケージの宣言を見ているため、ステートメント

cage.add(new Lion()); 

は、どちらかのコンパイルされないでしょう

私が知っているジェネリックの最も良い説明はO'Reilly's Java in a Nutshellです。この章は、無料のオンライン - part 1part 2です。

+0

とcage.add(新しいLion())もコンパイルされません。 – maks

+0

固定ありがとうございます。 –

+1

Javaのチュートリアルによると、 "super"によれば、Animalのスーパータイプであるすべての型を保持できます: "コード<?super Animal>は、" Animalのスーパータイプである未知の型自体""。しかしライオンもバタフライも動物のスーパータイプではありません。 – maks

関連する問題