自动装箱/自动拆箱不适用于有界类型参数

时间:2017-07-10 10:58:59

标签: java generics autoboxing

以下是我要做的事情:

class MyNumbers<T extends Number>{

    private T[] array;

    MyNumbers(T[] array){
            this.array = array;
        }
    public void setArray(T[] array){
        this.array = array;
    }
    public T[] getArray(){

            return this.array;
        }


    public double avarage(){

            double avg =0.0;
            double sum =0.0;
            for(T t: array){
                    sum += t.doubleValue(); // working
                    sum = sum+ t; // not working

                }
                return sum/array.length;            }
}

根据自动装箱和取消装箱规则sum = sum+ t;应该有效。但是因为T已经使用Number class扩展了。

以下是我尝试使用以下类型的内容:

public class BoundedTypeParam{

    public static void main(String [] args){

        Integer[] ints = {1,2,3,4,5,6};
        MyNumbers<Integer> stats4Ints = new MyNumbers<>(ints);

        System.out.println("Avg is same : "+ stats4Ints.avarage());

    }

}

我遗失的任何规则/概念。

PS。我知道可再生类型,擦除

2 个答案:

答案 0 :(得分:6)

这与泛型无关。如果用数字代替T,它就不会起作用。

没有从Number类型到某种原始类型的拆箱转换,因此Number不能是数字运算符的操作数。

以下代码无法通过编译,原因与您的代码完全相同 - The operator += is undefined for the argument type(s) double, Number

Number n = 5;
double sum = 0.0;
sum += n;

答案 1 :(得分:0)

阵列没有被删除,类型coersion根本不适用于它们。 double[]永远不会与Double[]相同,而且Number[]都不会class Example<T extends Number> { private T[] arr; }

通过绑定类型变量:

class com.Example {
  private Number[] arr;
}

您在运行时实际拥有的是:

for(T t: array) {
  <...snip...>
}

这反过来意味着以下代码:

for (Number t: array) {
  <...snip...>
}

在此代码中编译:

Number

正如您所看到的,没有关于它是什么类型的数据的信息,并且Java没有定义任何适用于BigInteger类的运算符,这可以通过任何执行自定义数字的库来证明,甚至JDK本身使用BigDecimal和{{1}}等类。