List <something>和List <! - 之间有什么区别?扩展某事 - >?</something>

时间:2013-09-21 17:52:58

标签: java generics

这两个List之间有区别吗?

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 个答案:

答案 0 :(得分:10)

List<Something>Something类型的对象列表。 List<? extends Something>是某种特定类型的对象列表,其中包含Something

因此,List<Object>可以包含任何扩展Object的类的对象。 但List<? extends Object>只能初始化或指定为扩展Object的特定类的对象列表

什么时候有用?假设您要编写一个方法,该方法需要List Objects并打印每个项目:

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传递给print2print2将接受List<Integer>List<String>等。

另一方面,您无法在print2内的列表中添加任何内容,因为print2不知道所使用的Object的具体子类型。因此,您只能在不必向? extends ...添加任何内容的方法中使用List

答案 1 :(得分:2)

正如其他人所提到的,List<Something>Something类型的对象列表,而List<? extends Something>将被初始化为不同对象类型的列表,只要该对象类型扩展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>();
    }

}

答案 2 :(得分:1)

List<Something>表示实施应该类似于ArrayList<Something>。但另一个案例List<? extends Something>表示实现可以是ArrayList<Something>ArrayList<SomethingChild>,其中SomethingChild扩展Something

您可以指定

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

而你不能分配

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

将导致编译错误。

您可以了解更多有关泛型中使用的泛型和通配符以获得一些明显性的信息

答案 3 :(得分:0)

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