-2

在 JAVA 泛型中,为什么这无效:

List<?> l = new ArrayList()<?>;

考虑到这是有效的:

public interface someList<?>{}

有两个无界通配符。在我看来,它们都相当于:

List l = new ArrayList();

public interface someList {}

我哪里错了?

4

4 回答 4

2

List<?>表示任何一种类型。为了让您作为程序员从类型检查中受益,设计师决定您需要在实例化期间提供一种类型。

如果你想要充分的灵活性,List<?> l = new ArrayList<Object>()这是要走的路。

通配符?只是一种说法,是的,我想要泛型,但不关心哪种类型。与无泛型变体不同,您仍然会在必要时获得类型检查和编译器警告。

于 2013-07-17T22:06:18.647 回答
2

因为,你不能实例化一个ArrayList未知类型

您可以实例化一个ArrayList原始类型

 new ArrayList();

或者,您可以实例化ArrayListObject某些特定的已知类型。

new ArrayList<Object>();
new ArrayList<String>();
于 2013-07-17T22:08:51.963 回答
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),所以它只用作生产者。除了没有任何东西可以生产——它是空的。那么为什么你会想要这个呢?

于 2013-07-18T03:27:05.763 回答
0

因为你试图构造一个泛型类型的对象,这是无稽之谈。如果创建了一个对象,它可能不会同时具有多种类型,因为 Java 不模拟量子世界。通配符类型表示预先不知道类型参数,但是当您有值时它将是一些具体的类型。

这并不等同于List l = new ArrayList();因为后者确实只允许静态类型 Object 的值,但是在泛型的帮助下,您可以将类型限制为任何引用类型。(尽管此信息仅在编译时存在)

于 2013-07-17T22:08:46.797 回答