泛型中的有界类型
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 的功能(Integer
、Double
、Float
等...)。 Number
的许多子 class 没有此功能(例如 BigInteger
、BigDecimal
等...)。
由于第一个代码段中的泛型类型参数可以是任何扩展 Number
的类型,它不一定具有自动拆箱功能,因此您必须告诉编译器如何转换 T
到可以作为除法运算符的操作数的数字原始类型。
在你的第二个片段中,T
没有界限,所以它可以是任何东西。 /
运算符没有为任意类型定义。它是为数字操作数定义的。因此,当 num
是某种任意引用类型时,编译器无法将 /
应用于 1
和 num
。
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.
在你的情况下,这两个你都没有做。
举个例子,为什么我需要在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 的功能(Integer
、Double
、Float
等...)。 Number
的许多子 class 没有此功能(例如 BigInteger
、BigDecimal
等...)。
由于第一个代码段中的泛型类型参数可以是任何扩展 Number
的类型,它不一定具有自动拆箱功能,因此您必须告诉编译器如何转换 T
到可以作为除法运算符的操作数的数字原始类型。
在你的第二个片段中,T
没有界限,所以它可以是任何东西。 /
运算符没有为任意类型定义。它是为数字操作数定义的。因此,当 num
是某种任意引用类型时,编译器无法将 /
应用于 1
和 num
。
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.
在你的情况下,这两个你都没有做。