【问题标题】:Generic methods tutorial [closed]泛型方法教程 [关闭]
【发布时间】:2021-09-18 15:27:50
【问题描述】:

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 &lt;T&gt; double sumOfList(List&lt;T extends Number&gt; list) 是非法的?
  2. public static &lt;T extends Number&gt; double sumOfList(List&lt;T&gt; list) 是否等效?如果是这样,是不是风格不太好?
  3. 在使用上述代码时,为什么写System.out.println("sum = " + sumOfList&lt;Integer&gt;(li));是非法的?

【问题讨论】:

    标签: java generics generic-list


    【解决方案1】:
    1. 为什么放不合法

    因为那不是语法。

    T 是一个类型变量,必须在声明类型变量的位置(在方法返回类型之前的 &lt;&gt; 内)指定边界,而不是在哪里使用它(与类型变量的类型相同)变量必须在声明的地方指定,而不是在使用的地方,例如String foo,而不是foo.&lt;String&gt;contains("a"))。

    1. ...是否等效?

    不完全是。

    声明一个类型变量并在List&lt;T&gt; 中使用它的好处是您可以在方法中声明该类型的变量。

    例如:

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

    List&lt;? extends Number&gt; 是不合法的,但List&lt;T&gt; 是合法的。

    您还可以在方法的返回类型和/或其他参数中使用T

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

    1. 使用上述代码时,为什么写不合法

    因为那不是语法。

    但是,你可以写:

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

    (或者例如this.&lt;Integer&gt;sumOfList(...),如果它是一个非静态方法)

    &lt;&gt; 位于方法名之前,方法调用需要限定。

    这个&lt;Integer&gt; 有时被称为"type witness",尽管这不是规范中定义的术语。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-01
      • 2016-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-16
      • 2014-03-05
      相关资源
      最近更新 更多