是否可以为Java中的数字框类型编写通用的1方法?
作者:互联网
This is NOT homework.
第1部分
是否可以编写通用方法,如下所示:
<T extends Number> T plusOne(T num) {
return num + 1; // DOESN'T COMPILE! How to fix???
}
如果不使用一堆instanceof和casts,这可能吗?
第2部分
编译以下3种方法:
Integer plusOne(Integer num) {
return num + 1;
}
Double plusOne(Double num) {
return num + 1;
}
Long plusOne(Long num) {
return num + 1;
}
是否可以编写将T仅绑定到Integer,Double或Long的通用版本?
解决方法:
第1部分
对此没有令人满意的解决方案,因为java.lang.Number
没有指定任何对计算Number的后继有用的东西.
您必须对数字框类型进行instanceof检查,并专门处理每种情况.另请注意,您可能会获得Number的instanceof,该实例不是数字框类型,例如BigInteger,AtomicLong和Number的可能未知的子类(例如Rational等).
第2部分
看起来很欺骗,在这里.这三种方法看起来很相似,但是自动装箱/拆箱隐藏了以下事实:它们在字节码级别上实际上有很大的不同:
Integer plusOne(Integer);
Code:
0: aload_1
1: invokevirtual #84; //int Integer.intValue()
4: iconst_1
5: iadd
6: invokestatic #20; //Integer Integer.valueOf(int)
9: areturn
Double plusOne(Double);
Code:
0: aload_1
1: invokevirtual #91; //double Double.doubleValue()
4: dconst_1
5: dadd
6: invokestatic #97; //Double Double.valueOf(double)
9: areturn
Long plusOne(Long);
Code:
0: aload_1
1: invokevirtual #102; //Long Long.longValue()
4: lconst_1
5: ladd
6: invokestatic #108; //Long Long.valueOf(long)
9: areturn
这3种方法不仅在不同类型上调用不同的xxxValue()和valueOf()方法,而且将常数1推入堆栈的指令也不同(iconst_1,dconst_1和lconst_1).
即使可以绑定< T = Integer | Long | Double>之类的通用类型,这3种方法也不能通用化为一种方法,因为它们包含非常不同的指令.
标签:bounded-wildcard,java,generics 来源: https://codeday.me/bug/20191010/1888539.html