2010-10-13 157 views
10

我想创建一个方法来比较一个数字,但可以有一个输入是任何数字的子类。Java泛型和数字类

我已经看过以下方式做这个...

public static <T extends Number> void evaluate(T inputNumber) { 
    if (inputNumber >= x) { 
    ... 
    } 
} 

我需要得到实际的灵长类动物之前,我可以进行比较,数类有方法来检索每个灵长类动物,但我想要一个干净的方式来选择正确的方法。

这可能吗?

干杯

+0

相关:【JAVA:泛型方法和数字] (http://stackoverflow.com/questions/3850970/java-generic-methods-and-numbers)。 – BalusC 2010-10-13 11:44:32

回答

4

不幸的是,没有办法使用if/else块从包装类型中获取原始类型。

问题是,它不可能以通用的方式实现这样的方法。这里有一些看起来可能的方法,可以期望在数字类中找到:

public abstract X getPrimitiveValue(); 

这将是很好的,不是吗?但是这是不可能的。有没有可能的X上可以超过int抽象,floatdouble

public abstract Class<?> getCorrespondingPrimitiveClass(); 

这没有帮助的,因为没有办法实例的原始类。

因此,您可以做的唯一一件事对所有类型都是通用的,即使用longValue()doubleValue()方法,但是如果您处理的是错误类型,则会丢失信息。

因此否:java编号层次结构不适合以通用的方式解决这些问题。

0

在这种情况下,你可以用普通的方法,不使用泛型

+0

所以,如果方法是接受一个double或一个整数,那么我需要两个不同签名的方法,或者我错过了什么? – 2010-10-13 11:32:58

+0

@Mr_R:如果您使用Java 5,则自动装箱会将其转换为Double和Integer,这两者都实现Number。 – 2010-10-13 11:40:46

+2

利用多态性,只需提供一个“评估(数量)”方法 – 2010-10-13 11:45:50

8

Number API不提供一个干净的方式来获得的价值;您必须使用instanceof

一种解决方案是将这些值“折叠”为两种类型:longdouble。这样,您可以使用此代码:

if(inputNumber instanceof Float || inputNumber instanceof Double) { 
    double val = inputNumber.doubleValue(); 
    ... 
} else { 
    long val = inputNumber.longValue(); 
    ... 
} 

请注意,这仅适用于本标准编号类型,但Number也受到了很多其他类型的(AtomicIntegerBigDecimal)的实现。

如果你想支持所有类型的,一招就是用BigDecimal

BigDecimal value = new BigDecimal(inputNumber.toString()); 

,应始终工作,并为您提供最精确的结果。

2

<T extends Number>方法总是麻烦,因为你不能真正做任何事情的数字(所有的操作符都为儿童定义)。您需要为Number的每个孩子做一大堆instanceof,并通过转换为子类型来处理该情况。或者(我认为更好 - 这就是Sun做这件事的方式)就是为每个孩子类型设置一个方法,可能利用拳击/取消装箱操作,如+, - ,>等,这是可能的(所有的包装,不是对于BigInteger/BigDecimal或任何自定义类型)。

1

如果它真的只是参数比较同类型参数的另一个值那么你可以做以下的(只是在T x为了简单相加)

public static <T extends Number & Comparable<? super Number>> int evaluate(T inputNumber, T x) { 
      if (inputNumber.compareTo(x) > 0) { ... } 
    }