Generics wildcards: "? T" works, but "? Extends T" doesn't?

My question is about generics in Java 7. Suppose we have a class hierarchy like this:

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

Like the Java Generics Tutorial

We also have a class

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

And here is the code that uses these classes:

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   
    }

Question number 1:

I read here about these issues, but it was just how Cage<?>. But I tell the compiler <? extends Animal>, so type Tin Cage<T>will be any of the subtypes of type Animal. So why is it still giving a compile-time error?

Question number 2:

If I specify Cage<? super Animal> cage = ...instead Cage<? extends Animal> cage = ..., everything will be fine, and the compiler will not say anything bad. Why does it work fine in this case, but in the above example it fails?

+5
1

. "" , , - , , , ? super Animal Animal. "extends" , - , , , :

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

, , , ,

cage.add(new Butterfly());   

.

cage.add(new Lion());

, Java - Cage<? extends Animal> - , (Cage<Lion>).

, , O'Reilly Java . - 1 2.

+6

All Articles