我已经阅读了应该阻止您将 a 添加到 a的泛型 get 和 put 规则:Banana
List<? extends Fruit>
public abstract class Fruit { }
public class Banana extends Fruit { }
public class Apple extends Fruit { }
List<? extends Fruit> lst = new ArrayList<>();
lst.add(new Banana()); // Compile error "The method add(capture#6-of ? extends Fruit) in the type List<capture#6-of ? extends Fruit> is not applicable for the arguments (Banana)"
我知道,如果您没有编译错误,您将能够:
List<? extends Fruit> lst = new ArrayList<>();
lst.add(new Banana());
lst.add(new Apple());
这听起来是错误的,因为您在同一个列表中获得了不同的对象类型(我看到@Tom Hawtins 的回答解释了原因,我相信他:)(虽然我找不到它的链接))。
但是,如果您执行以下操作:
public class ListFruit implements List<Fruit> {
List<Fruit> list;
public ListFruit() {
list = new ArrayList<>();
}
@Override public int size() { return list.size(); }
// All delegates of "list"
@Override public List<Fruit> subList(int fromIndex, int toIndex) { return list.subList(fromIndex, toIndex); }
}
然后做:
ListFruit lst = new ListFruit();
lst.add(new Banana());
lst.add(new Apple());
for (Fruit fruit : lst)
System.out.println(fruit.getClass().getName());
你没有得到编译错误,以及以下(预期的)输出:
Banana
Apple
我这样做是否违反了任何合同?还是我在规避保护并且不应该这样做?