4

List这两个s有区别吗?

List<Something> a;
List<? extends Something> b;

我知道例如

List<Object> a;
List<?> b;
List c;

List<Something> a;
List<? extends SomeInterfaceSomethingImplements> b;

都是不同的,但是这些呢?如果Something替换为 ,它会有所不同Object吗?

List<Object> a;
List<? extends Object> b;
4

4 回答 4

10

List<Something>是类型对象的列表SomethingList<? extends Something>是扩展的某些特定类型的对象列表Something

所以,List<Object>可以有任何扩展类的对象Object。但List<? extends Object>只能初始化或分配为扩展的特定类的对象的列表Object

这什么时候有用?假设您要编写一个方法,该方法采用 a ListofObjects并打印每个项目:

void print(List<Object> list) {
    for (Object obj: list) {
        System.out.println(obj)
    }
}

现在,假设您有一个List<Integer>. 您不能将它传递给上述方法,因为print需要List<Object>, 并且List<Integer>不能分配给List<Object>. 为了解决这个问题,我们重新定义print为:

void print2(List<? extends Object> list) {
    for (Object obj: list) {
        System.out.println(obj)
    }
}

现在,我们可以将 Object 的任何子类的 List 传递给print2. 会print2接受List<Integer>List<String>

另一方面,你不能在里面的列表中添加任何东西print2,因为print2不知道使用的具体子类型Object。因此,您? extends ...只能在不需要向List.

于 2013-09-21T17:56:33.770 回答
2

正如其他人所提到的,List<Something>是 type 的对象列表Something,而List<? extends Something>只要对象类型 extends ,就会被初始化为不同对象类型的列表Something

List<Object>将是类型对象的列表Object

List<? extends Object>可以初始化为扩展的任何数据类型的列表Object

Object下面是一些代码,显示了使用比较时会发生什么? extends Object

import java.util.ArrayList;

public class test {
    class A {}

    public static void main(String[] args) {
        // No error
        ArrayList<Object> arrObj = new ArrayList<Object>();

        // Error
        ArrayList<Object> arrObj2 = new ArrayList<A>();

        // No Error
        ArrayList<? extends Object> arrExt = new ArrayList<Object>();

        // No Error
        ArrayList<? extends Object> arrExt2 = new ArrayList<A>();
    }

}
于 2013-09-21T17:59:33.717 回答
1

List<Something>意味着实现应该类似于ArrayList<Something>. 但另一种情况List<? extends Something>意味着实现可以是任何类似ArrayList<Something>ArrayList<SomethingChild>where SomethingChildextends Something

你可以分配

List<? extends Something> list = new ArrayList<SomethingChild>();

而你不能分配

List<Something> list = new ArrayList<SomethingChild>();

这将导致编译错误。

您可以了解有关泛型和泛型中使用的通配符的更多信息,以获得一些洞察力

于 2013-09-21T17:56:53.647 回答
0

第一个是对象类型的集合,第二个是对象的子类型的集合。

于 2013-09-21T18:02:14.327 回答