通配符java扩展

时间:2013-09-24 19:16:14

标签: java wildcard extends

请考虑以下代码:

List<? extends Integer> lst= new ArraList<Integer>();
lst.add(5);//Compile error
lst.get(5);//OK

在第二个字符串中我们有编译错误,因为我们必须保证在List<? extends Integer>的所有潜在子类型中都有方法add(int),编译器知道它只有null,第三个字符串返回unknow类型,编译器将他转换为Object,不是吗?

3 个答案:

答案 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方法),因此它不允许它。尽管Integerfinal并且不允许子类,但仍会发生这种情况。

对于get方法,编译器知道返回类型是某种Integer,因此它允许调用并将隐式强制转换为Integer