Java Generics WildCard:<! - ? extends Number - > vs <t extends =“”number =“”> </t>

时间:2012-07-16 01:05:15

标签: java generics

这两个功能有什么区别?

static void gPrint(List<? extends Number> l) {
    for (Number n : l) {
        System.out.println(n);
    }
}

static <T extends Number> void gPrintA(List<T> l) {
    for (Number n : l) {
        System.out.println(n);
    }
}

我看到相同的输出。

4 个答案:

答案 0 :(得分:39)

不同之处在于您在使用通配符时无法引用T

你现在不对,所以“没有区别”,但是这里有你如何使用T来改变:

static <T extends Number> T getElement(List<T> l) {
    for (T t : l) {
        if (some condition)
            return t;
    }
    return null;
}

这将返回与传入的相同类型。例如,这些将编译:

Integer x = getElement(integerList);
Float y = getElement(floatList);

答案 1 :(得分:38)

在这种情况下没有区别,因为T永远不再使用。

声明T的原因是您可以再次引用它,从而将两个参数类型或返回类型绑定在一起。

答案 2 :(得分:7)

T是一种有界类型,即您使用的任何类型,您必须坚持使用Number扩展的特定类型,例如如果您将Double类型传递给列表,则无法将Short类型传递给T,因为Double类型为?且该列表已受该类型的限制。相反,如果您使用wildcardNumber),则可以使用&#34;任何&#34;扩展Short的类型(将Double和{{1}}添加到该列表中。)

答案 3 :(得分:-1)

使用T时,您可以在列表上执行所有类型的操作。但是当你使用时,你无法执行添加。

T - 与具有完全访问权限的对象引用相同 ? - 提供部分访问权限

static void gPrint(List<? extends Number> l) {
 l.add(1); //Will give error
for (Number n : l) {
    System.out.println(n);
}

static <T extends Number> void gPrintA(List<T> l) {
l.add((T)1); //We can add
for (Number n : l) {
    System.out.println(n);
}