列表<>或列表<对象>

2022-09-02 10:22:34

我有一个方法,其参数应该是“任何东西的列表”。该方法不会修改列表的内容。将此方法定义为更正确吗?

void foo(List<?> list) {
}

void foo(List<Object> list) {
}

究竟有什么区别?


答案 1

简短的回答,使用将允许您接受类似的东西,而使用则不会。List<?>List<String>List<Object>

这在官方泛型跟踪中进行了讨论,这里这里

[...]这是一个使用泛型(以及新的for循环语法)编写它的天真尝试:

   void printCollection(Collection<Object> c) {
       for (Object e : c) {
           System.out.println(e);
       }
   }

问题是这个新版本比旧版本有用得多。虽然旧代码可以使用任何类型的集合作为参数来调用,但新代码只采用 ,正如我们刚刚演示的那样,这不是各种集合的超类型!
那么,各种馆藏的超类型是什么呢?它写为Collection<?>(发音为“未知集合”),即元素类型与任何内容匹配的集合。由于显而易见的原因,它被称为通配符类型。我们可以这样写:Collection<Object>

   void printCollection(Collection<?> c) {
       for (Object e : c) {
           System.out.println(e);
       }
   }

现在,我们可以用任何类型的集合来调用它。


答案 2

具有参数化类型,这实质上意味着您可以添加列表中的所有对象。List<Object>Object

但是,这意味着这是一个未知数列表。只要您不打算向列表中添加任何内容,它基本上与以下情况相同,但您必须担心以下情况:List<?>List<Object>

List<?> unknownList = new ArrayList<String>();
unknownList.add(new Object()); //Compilation error.

(在本例中)表示您只能添加 的值 或 是 的子类型。?StringString

如果您只是要循环访问列表并检索值,则本质上是相同的。List<?>List<Object>

更多信息请点击这里


推荐