Java Generics:List <e>和List <! - ? - >?</e>之间有区别吗?

时间:2013-12-14 20:04:11

标签: java generics

以下代码之间有什么区别吗?

public static <E> void printElements(List<E> list) {
    for (E elem : list) {
        System.out.println(elem);
    }
}

public static void printElements(List<?> list) {
    for (Object elem : list) {
        System.out.println(elem);
    }
}

如果是,有人可以解释差异以及何时使用什么?

2 个答案:

答案 0 :(得分:0)

第一个语句使用Bounded Type Paramater E,而第二个语句使用Wildcard Parameter。第一个语句的界限是“限制可以在参数化类型中用作类型参数的类型”。在您的情况下,?表示它是某种类型的列表,但我们不知道它是什么。它是无界的类型。

答案 1 :(得分:0)

虽然不直观,但存在差异。我建议您阅读the java standard tutorial了解详情。

基本上,两者是不同且不兼容的类型。 List<E>可以存储扩展,子类或实际为类型E的对象,但它是自己的类型。即使您可以向List<String>添加List<Object>,也无法从String引用中引用List<Object>

List<?>表示它是一个列表引用,可以引用它的任何参数化引用。 List<?>可以引用List<String>List<Integer>。当它受到某些接口或类的限制时,它是最有用的。例如,下面的第一个方法(改编自java标准教程)只需要List<Number>,而不是List<Double>List<Integer>

public static double sumOfList(List<Number> list) {
    double s = 0.0;
    for (Number n : list)
        s += n.doubleValue();
    return s;
}

但以下使用通配符的代码可以使用List<Double>List<Integer>。它更灵活。

public static double sumOfList(List<? extends Number> list) {
    double s = 0.0;
    for (Number n : list)
        s += n.doubleValue();
    return s;
}