泛型中的有界类型

Bounded Types in generics

举个例子,为什么我需要在reciprocal()中使用doubleValue()(为此需要扩展Number class),因为java中有自动拆箱功能它拆箱存储在 num 中的数字对象并可以计算 num 的倒数和 return 双精度值?

class gen<T extends Number>{
     T num ;

     gen(T n ){
         num = n ;
     }

     double reciprocal() {
         return (1 / num.doubleValue()) ;
     }
 }


public class demo  {

    public static void main(String[] args) {
        gen<Integer> ob = new gen<Integer>(5) ;
        System.out.println(ob.reciprocal()) ;
    }

}

另外,为什么我写不出如下所示的相同代码? P.S。 : 以下代码显示 reciprocal() 方法中的错误:

class gen<T>{
     T num ;

     gen(T n ){
         num = n ;
     }

     double reciprocal() {
         return (1 / num) ;
         // it shows error in the above step. it says "operator / is undefined
     }
 }


public class demo  {

    public static void main(String[] args) {
        gen<Integer> ob = new gen<Integer>(5) ;
        System.out.println(ob.reciprocal()) ;
    }

}

自动拆箱不是 Number class 的功能,它是 某些 子 class 的功能(IntegerDoubleFloat 等...)。 Number 的许多子 class 没有此功能(例如 BigIntegerBigDecimal 等...)。

由于第一个代码段中的泛型类型参数可以是任何扩展 Number 的类型,它不一定具有自动拆箱功能,因此您必须告诉编译器如何转换 T 到可以作为除法运算符的操作数的数字原始类型。

在你的第二个片段中,T 没有界限,所以它可以是任何东西。 / 运算符没有为任意类型定义。它是为数字操作数定义的。因此,当 num 是某种任意引用类型时,编译器无法将 / 应用于 1num

Oracle文档(https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html)中关于拆箱的描述是:

The Java compiler applies unboxing when an object of a wrapper class is:

  • Passed as a parameter to a method that expects a value of the corresponding primitive type.
  • Assigned to a variable of the corresponding primitive type.

在你的情况下,这两个你都没有做。