通用方法教程

Generic methods tutorial

https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html中,建议实现一个方法

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

然后用

调用它
List<Integer> li = Arrays.asList(1, 2, 3);
System.out.println("sum = " + sumOfList(li));
  1. 为什么输入 public static <T> double sumOfList(List<T extends Number> list) 是非法的?
  2. public static <T extends Number> double sumOfList(List<T> list)是否等价?如果有,是不是风格不太好?
  3. 使用上述代码时,为什么写System.out.println("sum = " + sumOfList<Integer>(li));是非法的?
  1. Why is it illegal to put

因为那不是语法。

T 是类型变量,必须在声明类型变量的位置(在方法 return 类型之前的 <> 内)指定边界,而不是在它所在的位置used(就像变量的类型必须在声明的地方指定,而不是在使用的地方指定,例如String foo,而不是foo.<String>contains("a"))。

  1. Is ... Equivalent?

不完全是。

声明类型变量并在 List<T> 中使用它的优点是您可以在方法中声明该类型的变量。

例如:

T element = list.get(0);
list.set(0, element);

对于 List<? extends Number> 是不合法的,但对于 List<T>.

是合法的

您还可以在方法的 return 类型中使用 T and/or 其他参数。

但是,如果您不需要做任何这些事情,您就不需要类型变量,所以不要声明类型变量,就像您不应该声明不需要的变量一样。

  1. When using the aforementioned code, why is it illegal to write

因为那不是语法。

不过,你可以这样写:

System.out.println("sum = " + TheContainingClass.<Integer>sumOfList(li));

(或者例如 this.<Integer>sumOfList(...),如果它是一个非静态方法)

<>在方法名之前,方法调用需要限定。

<Integer> 有时称为 "type witness",尽管这不是规范中定义的术语。