在JAVA泛型中,为什么这不起作用:
List<?> l = new ArrayList()<?>;
考虑到这是有效的:
public interface someList<?>{}
有两个无界的通配符。在我看来,它们都相当于:
List l = new ArrayList();
和
public interface someList {}
我哪里错了?
答案 0 :(得分:2)
List<?>
表示任何一个类型。作为程序员从中获益,设计人员决定在实例化过程中需要提供 one 类型。
如果您想要充分的灵活性,List<?> l = new ArrayList<Object>()
是可行的方法。
通配符?
只是一种说法,是的,我想要泛化但不关心哪种类型。与generic-less变体不同,您仍然可以在必要时获得类型检查和编译器警告。
答案 1 :(得分:2)
因为,您无法实例化未知类型的ArrayList
。
您可以实例化{{1>} 原始类型。
ArrayList
或者,您可以实例化{{1>} 对象或某些特定的已知类型。
new ArrayList();
答案 2 :(得分:1)
这样做:
class CrazyBogusUnrelatedType { }
List<?> l = new ArrayList<CrazyBogusUnrelatedType>();
真。这是100%正确,100%类型安全。这表明你可以在那里使用任意的东西。它也证明了这样做的荒谬。
在我看来,它们都相当于:
甚至没有远程关闭。它们是完全相反的。
使用List l
,您可以添加任何内容。 使用List<?> l
,除了null
之外,您无法添加任何内容。所以基本上,使用List<?> l = new ArrayList()<?>;
初始化的列表几乎完全没用,因为它是空的,由于您只能向其添加null
,因此它可以包含的唯一内容是null
元素。
这是使用通配符的结果。回想一下PECS(生产者extends
,消费者super
)规则 - 这里有一个extends
通配符(无界通配符大多数用于extends Object
),所以它仅作为制作人使用。除了没有什么可以产生 - 它是空的。那你为什么要这个呢?
答案 3 :(得分:0)
因为你试图构造泛型类型的对象,这是无稽之谈。 如果创建了一个对象,它可能不会同时具有多种类型,因为Java不会对量子世界进行建模。通配符类型表示事先不知道类型参数,但是当您有值时它将是一些具体类型。
这不等同于List l = new ArrayList();
,因为后者仅允许静态类型Object的值,但在泛型的帮助下,您可以将类型约束为任何引用类型。 (虽然此信息仅在编译时存在)