2015-03-21 4 views
1

У меня есть следующие классы.Java Generics Ограничение подстановки не может установить

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 {} 

Мое замешательство возникает, когда я рассматриваю следующие случаи.

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

и

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

Если ? extends Fruit означает, что я могу передать то, что есть по крайней мере Fruit (или что-нибудь, который реализует или расширяет), почему это, что я не могу пройти в Apple типа? Я не вижу никакой разницы между этими двумя случаями, если пропускание Apple типа во втором случае работает, потому что Apple является потомком Fruit ...

ответ

1

Basket<? extends Fruit> не означает, что корзину, которая может содержать любой объект до тех пор, как это подтип Fruit. Это означает корзину неизвестного типа T, распространяющуюся на Fruit. Например, это может быть Basket<Apple>, a Basket<Orange> или Basket<Fruit>. Поскольку это может быть Basket<Orange>, вы не можете установить элемент в Apple.

Basket<Fruit> является корзиной Fruit. Любой фрукт будет делать.

+0

Так как у нас есть возможность передавать более одного типа фруктов, Java запрещает методы, содержащие '' в качестве параметра? – Dimitri

+0

Да. E неизвестно, потому что вы использовали подстановочный знак. Поэтому компилятор запрещает вам передавать Apple, потому что E может быть оранжевым. –

+0

Gotcha! Спасибо! – Dimitri