Java 泛型和 Number 类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3923081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java generics and the Number class
提问by Mr R
I want to create a method that compares a number but can have an input that is any of the subclasses of Number.
我想创建一个比较数字的方法,但可以有一个输入,它是 Number 的任何子类。
I have looked at doing this in the following manner...
我已经看过以以下方式执行此操作...
public static <T extends Number> void evaluate(T inputNumber) {
if (inputNumber >= x) {
...
}
}
I need to get the actual primative before I can perform the comparison, the Number class has methods to retrieve this for each primative but I want a clean way of selecting the correct one.
在执行比较之前,我需要获取实际的原始数据,Number 类具有为每个原始数据检索它的方法,但我想要一种干净的方法来选择正确的原始数据。
Is this possible?
这可能吗?
Cheers
干杯
采纳答案by Sean Patrick Floyd
Unfortunately there is no way to get the primitive type from the wrapper type without resorting to if/else blocks.
不幸的是,如果不求助于 if/else 块,就无法从包装器类型中获取原始类型。
The problem is that it just wouldn't be possible to implement such a method in a generic way. Here are some seemingly possible approaches which one could expect to find in the Number class:
问题是不可能以通用方式实现这样的方法。以下是人们可以期望在 Number 类中找到的一些看似可行的方法:
public abstract X getPrimitiveValue();
This would be nice, wouldn't it? But it's impossible. There is no possible X that could be an abstraction over int
, float
, double
etc.
这会很好,不是吗?但是这是不可能的。有没有可能的X可能是一个抽象了int
,float
,double
等。
public abstract Class<?> getCorrespondingPrimitiveClass();
This won't help either, because there is no way to instantiate primitive classes.
这也无济于事,因为无法实例化原始类。
So the only thing you can do that is common to all types is to use the longValue()
or doubleValue()
methods, but either way you are losing information if you're dealing with the wrong type.
所以你唯一能做的事情是使用longValue()
ordoubleValue()
方法,但如果你处理错误的类型,你会丢失信息。
So no: the java number hierarchy is just not suited to solve such problems in a generic way.
所以不:java 数字层次结构不适合以通用方式解决此类问题。
回答by Aaron Digulla
The Number
API doesn't offer a clean way to get the value; you have have to use instanceof
.
该Number
API不提供一个干净的方式来获得的价值; 你必须使用instanceof
.
One solution is to "fold" the values into two types: long
and double
. That way, you can use this code:
一种解决方案是将值“折叠”为两种类型:long
和double
。这样,您可以使用以下代码:
if( inputNumber instanceof Float || inputNumber instanceof Double ) {
double val = inputNumber.doubleValue();
...
} else {
long val = inputNumber.longValue();
...
}
Note that this only works for the standard number types but Number
is also implemented by a lot of other types (AtomicInteger
, BigDecimal
).
请注意,这仅适用于标准数字类型,但Number
也由许多其他类型 ( AtomicInteger
, BigDecimal
) 实现。
If you want to support all types, a trick is to use BigDecimal
:
如果你想支持所有类型,一个技巧是使用BigDecimal
:
BigDecimal value = new BigDecimal( inputNumber.toString() );
That should always work and give you the most exact result.
这应该始终有效并为您提供最准确的结果。
回答by jk3000
If it's really just about comparing the argument to another value of the same type parameter then you could do the following (just adding in T x
for simplicity)
如果它真的只是将参数与相同类型参数的另一个值进行比较,那么您可以执行以下操作(T x
为了简单起见,只需添加)
public static <T extends Number & Comparable<? super Number>> int evaluate(T inputNumber, T x) {
if (inputNumber.compareTo(x) > 0) { ... }
}
回答by Andrei Fierbinteanu
Methods with <T extends Number>
are always trouble, since you can't really do anything on a Number (all the operators are defined for the children). You would need to either do a ton of instanceof
for each child of Number and treat that case by casting to the subtype. Or (better I think - that's the way Sun does it) is to just have a method for each child type, possibly taking advantage of boxing/unboxing for operators like +,-,> etc. where that is possible (all wrappers, not for BigInteger/BigDecimal or any custom types).
with 方法<T extends Number>
总是很麻烦,因为你不能真正对 Number 做任何事情(所有的运算符都是为孩子定义的)。您需要为instanceof
Number 的每个子项执行大量操作,并通过转换为子类型来处理这种情况。或者(我认为更好 - 这就是 Sun 这样做的方式)只是为每个子类型提供一个方法,可能利用对 +、-、> 等运算符进行装箱/拆箱的优势,在可能的情况下(所有包装器,而不是用于 BigInteger/BigDecimal 或任何自定义类型)。
回答by Salandur
in this case you can use an ordinary method without generics
在这种情况下,您可以使用没有泛型的普通方法