У меня есть следующие классы.
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
? extends Fruit
означает, что я могу передать что-то, что является, по крайней мере, Fruit
(или чем-либо, что реализует или расширяет), почему я не могу пройти в типе Apple
? Я не вижу различий между этими двумя случаями, если передача второго типа Apple
во втором случае работает, потому что Apple
является потомком Fruit
...
Basket<? extends Fruit>
Basket<? extends Fruit>
не означает корзину, которая может содержать любой объект, если это подтип Fruit
. Это означает корзину с неизвестным типом T
расширяющим Fruit
. Например, это может быть Basket<Apple>
, Basket<Orange>
или Basket<Fruit>
. Поскольку это может быть Basket<Orange>
, вы не можете установить элемент в качестве Apple
.
Basket<Fruit>
- это корзина с Fruit
. Любой фрукт будет делать.
<E>
в качестве параметра?