代码:
List<? extends Integer> ints= new ArrayList<Integer>();
ints.add(3);//error
我仍然不明白它是如何运作的。的问题:
什么意思是CAP#1
?它是参考类型吗?我想,不,因为CAP#1不继承自Object
。我们可以写ints.add(null);//OK
而我们没有编译时间错误。但我们不能写null instanceof CAP#1;//compile-time error
。为什么我们无法实现CAP#1
:
CAP#1 c= new CAP#1();
从CAP#1
出现了什么?
答案 0 :(得分:4)
CAP#1
是由“?
”表示的隐式类型变量的编译器名称。没有这样的命名类型,但编译器需要为该类型创建占位符才能完成其工作。这个名字代表“捕获”。
在心理上将G<? extends T>
类型重写为∃CAP#1 extends T: G< CAP#1 >
会有所帮助。
您不能向带有通配符扩展类型的列表添加任何内容,因为您不知道该通配符代表什么。就像您无法将Snake
添加到List< Mammal >
一样,您无法将其添加到List< ? extends Animal >
,因为?
可能会代表Mammal
}。
但是,您可以在这种情况下添加null
,因为null
实际上是每个引用类型的成员,它必然包含?
可能代表的任何内容。
我经常想知道为什么Java不会将List< ? extends F >
视为与F
相同的最终类型List< F >
。也许是因为F
本身可以是通用的通配符类型,这意味着它仍然会有任意多种子类型。
除了Angelika Langer关于Java泛型的着名FAQ之外,我一直在我自己的列表中编译some things。
答案 1 :(得分:1)
表示Number或未知的子类。如果您获得这样的值,它将是一个数字,但您不能给出这种类型的值,因为您不知道哪个是有效的。
更多关注此答案: What is the difference between List<Number> and List<? extends Number>?