请考虑以下代码:
List<? extends Integer> lst= new ArraList<Integer>();
lst.add(5);//Compile error
lst.get(5);//OK
在第二个字符串中我们有编译错误,因为我们必须保证在List<? extends Integer>
的所有潜在子类型中都有方法add(int),编译器知道它只有null
,第三个字符串返回unknow类型,编译器将他转换为Object,不是吗?
答案 0 :(得分:1)
PECS. Producer extends, Consumer super.
List<? super Integer> lst= new ArrayList<Integer>();
lst.add(5);// No Compile error
列表是消费者现在,您将对象放入其中......
也是这个
lst.get(5);
是一个不同的蛋糕......你提供了你想要获得的整数索引 ......(更不用说Sotirios提到的内容:返回类型将是Object
in此案例。此外,在此角色中,列表是提供商 ...)
答案 1 :(得分:0)
您不能将除null
之外的任何内容添加到由通配符限定的List
,因为您永远不知道基础类型。
List<? extends Integer> lst= new ArrayList<Integer>();
lst.add(5); // Compile error
lst.get(5); // 5 is just the index
但是你可以获得一个元素,因为你知道它必须是Integer
(在这种情况下)。
很难用Integer
解释,因为它是一个无法扩展的类。但是拿这个
public class Foo {}
public class Bar extends Foo {}
public class Zoop extends Foo {}
你可以添加什么
List<? extends Foo> fooList = new ArrayList<Zoop>(); // could come from a method
?
即使运行时对象的泛型类型为? extends Foo
,该列表也会声明为Zoop
。因此编译器不能让你添加任何东西。但是你可以保证对Foo
个对象进行操作,这样你就可以很好地检索它们。
答案 2 :(得分:0)
一旦有List<? extends Integer>
,编译器就不知道它是Integer
还是子类型。除了null
之外,编译器无法确保添加任何内容的类型安全性(实际上,将任何内容传递给采用泛型类型参数的方法,包括add
方法),因此它不允许它。尽管Integer
是final
并且不允许子类,但仍会发生这种情况。
对于get
方法,编译器知道返回类型是某种Integer
,因此它允许调用并将隐式强制转换为Integer
。