泛型方法的返回类型(Java)

Gab*_*cco 6 java generics

我有这个通用功能:

public static <T extends Number> T sum(List<T> list){
    Number tot = 0;
    for(Number n: list){
        tot = tot.doubleValue() +  n.doubleValue();
    }
    return (T)tot;
}
Run Code Online (Sandbox Code Playgroud)

回想一下这段代码的主要内容:

public static void main(String[] args) {
    ArrayList<Integer> listInt = new ArrayList<>();
    listInt.add(3);
    listInt.add(5);
    listInt.add(6);
    listInt.add(8);
    System.err.println("Sum: " + Calcolatrice.sum(listInt))
}
Run Code Online (Sandbox Code Playgroud)

因此,我希望(作为listInt是一个整数的ArrayList),函数sum返回的值是T = Integer,在这种情况下,给我一个从Double到Integer的转换错误.结果的类型是Double,不会抛出任何错误.演员(T)tot没有所需的结果.

我想这是因为Java处理泛型站点阶段,但有人知道更好地解释为什么它以这种方式工作?

Fra*_*son 1

返回类型实际上是由于示例中末尾的强制转换然而结果的真实类型是. 显然这不是一个好的情况,但它发生是因为您在转换中明确告诉编译器返回值将与返回值具有相同的类型。Calcolatrice.sum(listInt)IntegersumDouble

这种情况意味着,如果您改为编写,Calcolatrice.sum(listInt).toString()您将得到 aClassCastException: java.lang.Double cannot be cast to java.lang.Integer因为您将调用Integer.toString()a Double。您的代码实际上所做的是System.out.println("Sum: "+ String.valueOf(Calcolatrice.sum(listInt)))有效的,因为它在调用之前向下转换为Object(从而解决了冲突)toString

正如 @TmTron 指出的那样,您不能像使用基元那样在装箱类型Double之间进行转换。Integer

IE

int i = (int) 2.0;
Run Code Online (Sandbox Code Playgroud)

遵循以下不同的规则:

Integer i = (Integer) new Double(2.0)
Run Code Online (Sandbox Code Playgroud)