使用通配符实例化通用对象

时间:2016-10-18 17:39:30

标签: java generics bounded-wildcard

我有一个班级

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

但这两个问题都提供了两个选项编译失败的原因。 我无法理解为什么以及如何允许最后一个。

2 个答案:

答案 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的类型是什么,你也应该在这里具体说明。