为什么我们需要Java中的纯<!-?->?

时间:2018-07-20 17:37:25

标签: java generics wildcard

为什么我们需要Java中的纯<?>? 传递的任何内容只能用作Object吗?因此,它与强制转换为Object的任何类一样有用(只能使用9种方法)

谢谢


我的意思是,如果您有List <? >列表,则只能将项目用作对象。这意味着list.get(0)给您对象,仅此而已。是的,我也可以在这里存储任何东西,但是对您有用吗?就像您拥有一件昂贵的好东西,然后将其放入垃圾箱一样。您只能从垃圾箱中获取垃圾。同样,您可以将任何类的任何好的对象放入List,但仅通过9种方法从那里获取Object。

2 个答案:

答案 0 :(得分:6)

在两种情况下,无限制的通配符是一种有用的方法:

  • 如果您正在编写可以使用Object类中提供的功能实现的方法。

  • 当代码使用通用类中不依赖于类型参数的方法时。
    例如,List.sizeList.clear。实际上,Class<?>之所以经常使用是因为Class<T>中的大多数方法都不依赖于T

例如,请参见Collections.swap方法:

public static void swap(List<?> list, int i, int j) {
    final List l = list;
    l.set(i, l.set(j, l.get(i)));
}

知道类型无助于交换List中的两个元素,因此使用了无界通配符。您传入List-任何List-,该方法交换索引元素。没有类型参数值得担心。

有关更多信息,请参见:Unbounded Wildcards.

答案 1 :(得分:1)

我认为最好的答案是因为有时您实际上不知道某个类使用什么类型的参数。正如迈克尔指出的,List<?>List<Object>不同。因此?提供了不同的语义,这对于确保程序的正确性很有用。

考虑两个列表。一个列表是List<String>,另一个列表是List<Integer>。这两个都是Object,但是我们仍然不想将它们混淆。我们不想将String放在Integer列表中,反之亦然。因此,如果您有一个声明为List<?>的类型,则不能安全地将任何类型放入该列表中。 ?可以是StringInteger,但您不知道它是什么,也不想将它们混淆,因此您都不能放入。

OTOH,List<Object>只是对象列表,并且由于您声明它可以容纳任何对象,因此可以安全地将StringInteger都放入列表中。您说您不关心声明为Object类型的内容是什么,所以任何类型都可以。在我能想到的任何有意义的方式中,List<Object>等同于原始类型。这是您自己管理的列表,无需编译器的帮助。