Dimitri
Dimitri

Reputation: 1966

Java Generics Wildcard bounding cannot set

I have the following classes.

public class Basket<E> {
    private E element;

    public void setElement(E x) {
        element = x;
    }

    public E getElement() {
        return element;
    }
}

class Fruit {}
class Apple extends Fruit {}
class Orange extends Fruit {} 

My confusion comes when I consider the following cases.

Basket<? extends Fruit> basket = new Basket<>(); 
basket.setElement(new Apple()); // cannot set

and

Basket<Fruit> basket = new Basket<>(); 
basket.setElement(new Apple()); // okay!

If ? extends Fruit means that I can pass something that is at least a Fruit (or anything that implements or extends), why is it that I cannot pass in an Apple type? I cannot see any difference between the two cases if passing an Apple type in the second case works because Apple is a descendant of Fruit...

Upvotes: 1

Views: 38

Answers (1)

Paul Boddington
Paul Boddington

Reputation: 37655

Basket<? extends Fruit> does not mean a basket that can hold any object as long as it is a subtype of Fruit. It means a basket of some unknown type T extending Fruit. For example it could be a Basket<Apple>, a Basket<Orange> or a Basket<Fruit>. Because it could be a Basket<Orange>, you can't set the item to be an Apple.

Basket<Fruit> is a basket of Fruit. Any fruit will do.

Upvotes: 1

Related Questions