我有一个班级
public class OrderedBox<T> {}
编译器不允许创建这样的成员/局部变量。
OrderedBox<? extends T> testItems1 = new OrderedBox<? extends T>();
List<? extends T> testItems2 = new ArrayList<? extends T>();
它在运行时可以理解的原因,它不会保证插入对象的类型(由T限制的上限)并且将违反类型安全。
但它允许创建像这样的成员/局部变量。 为什么以及如何允许这样做?
private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>();
注意:
通过http://www.onjava.com/pub/a/onjava/excerpt/javaian5_chap04/index1.html
可能重复:
Creating new generic object with wildcard
Generics wildcard instantiation
但这两个问题都提供了两个选项编译失败的原因。 我无法理解为什么以及如何允许最后一个。
答案 0 :(得分:5)
单行变体的答案实际上是在您发布的第二个SO问题中解释的:Generics wildcard instantiation
One-liner会声明一种OrderedBox
,但不会创建它的实例。
private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>();
这表示你将拥有一个OrderedBox,但它没有说明哪一个。 尝试创建像
这样的实例时会遇到麻烦testItems.add(new OrderedBox<? extends T>())
因为那时你会修复这个类型。
答案 1 :(得分:0)
您的列表对象是bag a,您可以在其中保留许多OrderedBox对象
private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>();
编译时OrderedBox在其中的含义并不重要,当您尝试将对象插入该列表时,使用这种语法会导致问题。
你应该在声明一个类时使用泛型(通配符),但在为该类创建对象时,你应该具体如
private List<OrderedBox<Object>> testItems = new ArrayList<OrderedBox<Object>>();
编译器不允许
OrderedBox<? extends T> testItems1 = new OrderedBox<? extends T>();
因为在这里你没有说明,OrderedBox的类型是什么,你也应该在这里具体说明。