84

这两个功能有什么区别?

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

4 回答 4

51

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

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

于 2012-07-16T01:08:34.227 回答
49

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);
于 2012-07-16T01:15:43.660 回答
12

T是有界类型,即无论您使用什么类型,都必须坚持使用 extends 的特定类型Number,例如,如果您将Double类型传递给列表,则不能将Short类型按原样传递给它,并且列表已经受该类型的T限制Double类型。相反,如果使用?( wildcard),则可以使用扩展的“任何”类型Number(将Short和都添加Double到该列表中)。

于 2014-08-17T05:06:06.520 回答
-2

当您使用 T 时,您可以对 List 执行所有类型的操作。但是当你使用时你不能执行添加。

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);
}
于 2016-04-21T13:07:37.730 回答