是否可以在Java中为数字框类型编写通用的+1方法? [英] Is it possible to write a generic +1 method for numeric box types in Java?
问题描述
这不是功课。 >
是否可以编写一个泛型方法,如下所示:
< ; T扩展数字> T plusOne(T num){
return num + 1; //不编译!怎么修???
}
使用一堆
binstanceof $
第二部分
$ b $这是可能的吗?以下3种方法编译:
Integer plusOne(Integer num){
return num + 1;
}
Double plusOne(Double num){
return num + 1;
}
Long plusOne(Long num){
return num + 1;
}
是否可以编写一个通用版本来绑定
T 仅限于
整数
,Double
或Long
?
解决方案
第一部分
没有令人满意的解决方案,因为
java.lang.Number
没有指定任何对计算Number
的后继有用的内容。
您必须对
instanceof
检查数字框类型,并专门处理每个案例。还要注意,你可能得到一个不是数字框类型的instanceof Number
,例如,BigInteger
,AtomicLong
,以及可能未知的Number 子类例如 Rational
等)。
第2部分
在这里,看起来很欺骗。这三种方法可能看起来很相似,但autoboxing / unboxing隐藏了它们在字节码级别实际上非常不同的事实:
Integer plusOne(Integer);
代码:
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);
代码:
0:aload_1
1:invokevirtual#91; // double Double.dalue()
4:dconst_1
5:dadd
6:invokestatic#97; // Double Double.valueOf(double)
9:areturn
Long plusOne(Long);
代码:
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种方法不能泛化为一种方法,因为它们包含非常不同的指令。This is NOT homework.
Part 1
Is it possible to write a generic method, something like this:
<T extends Number> T plusOne(T num) { return num + 1; // DOESN'T COMPILE! How to fix??? }
Short of using a bunch of
instanceof
and casts, is this possible?
Part 2
The following 3 methods compile:
Integer plusOne(Integer num) { return num + 1; } Double plusOne(Double num) { return num + 1; } Long plusOne(Long num) { return num + 1; }
Is it possible to write a generic version that bound
T
to onlyInteger
,Double
, orLong
?解决方案Part 1
There is no satisfactory solution for this, since
java.lang.Number
doesn't specify anything that would be useful to compute the successor of aNumber
.You'd have to do
instanceof
checks for the numeric box types, and handle each case specially. Note also that you may get aninstanceof Number
that's none of the numeric box types, e.g.BigInteger
,AtomicLong
, and potentially unknown subclasses ofNumber
(e.g.Rational
, etc).Part 2
Look is very deceiving, here. The 3 methods may look alike, but autoboxing/unboxing hides the fact that they're actually very different at the bytecode level:
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
Not only are the 3 methods invoking different
xxxValue()
andvalueOf()
methods on different types, but the instruction to push the constant1
to the stack is also different (iconst_1
,dconst_1
, andlconst_1
).Even if it's possible to bind a generic type like
<T=Integer|Long|Double>
, the 3 methods are not genericizable into one method since they contain very different instructions.这篇关于是否可以在Java中为数字框类型编写通用的+1方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!