克服Java中的类型擦除

Har*_*hal 0 java generics type-erasure

我有一个客户类,我无法改变.

List<Integer> list1= Arrays.asList(1,2,3);
System.out.println("Total sum is:"+sum(list1));
printlist(list1);
List<Double> list2=Arrays.asList(1.0,2.0,3.0);
System.out.println("Total sum is:"+sum(list2));
printlist(list2);
Run Code Online (Sandbox Code Playgroud)

我在这里有业务逻辑

private static Object sum(List<? extends Number> list) {
    double sum = 0;
    for (Number i: list) {
        sum+=i.doubleValue();
    }     
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

所以我想返回6表示整数,6.0表示双精度数.我怎样才能做到这一点?我想根据类型将类型转换为int或double,但由于类型擦除,所有信息都会丢失.有人能帮我吗?

Ale*_*lor 5

列表中的对象在运行时仍具有与其关联的类型信息.唯一被删除的类型是泛型(即List在您的示例中).在编译时检查泛型,但不在生成的字节码中维护.这意味着您可以instanceof用来检查集合的内容:

private static Object sum(List<? extends Number> list) {
    Integer integerSum = 0;
    Double doubleSum = 0.0;
    boolean hasDouble = false;
    for (Number i: list) {
        if (i instanceof Integer) {
            integerSum += i.intValue();
        } else {
            doubleSum += i.doubleValue();
            hasDouble = true;
        }
    }
    if (hasDouble)
        return doubleSum + integerSum;
    return integerSum;
}
Run Code Online (Sandbox Code Playgroud)

该代码具有一定的特殊性,来处理混合列表,并且不处理Long,Short,Byte等正常.