13

我正在创建一个应该能够与任何类型的数字(float、int 等)的数组一起使用的类,所以这是我拥有的一种方法:

// T extends Number
public synchronized T[] average() {
    Number[] ret = new Number[queue[0].length];
    for (int i = 0; i < ret.length; ++i) {
        for (int j = 0; j < size; ++j) {
            ret[i] += queue[j][i]; // WTF ERROR?!
        }
        ret[i] /= size; // WTF ERROR?!
    }
    return (T[])ret;
}

除了这不会编译,因为“数字”没有实现“+=”或“/=”运算符。更糟糕的是,Java 的 Number 类甚至没有实现最基本的运算符,如“+”或“-”!如果java不让我编译它,我怎么能创建一个返回数字数组平均值的方法,因为它认为不能添加数字?!?!

4

7 回答 7

14

您误解了 Java 中数字的工作方式。该类Number是数字包装类( 、 等)的超类IntegerFloat可用于将基本类型(intfloat等)表示为对象,但它不适用于通常的算术运算符。

如果您打算使用算术运算符,请使用原始类型。如果您需要构建适用于所有数字数据类型的“通用”方法,您别无选择,只能构建同一方法的多个重载版本,每个数据类型一个,例如:

public  float[] average(float[][]  queue) {...}
public double[] average(double[][] queue) {...}

另请注意,这样的代码似乎适用于包装器类型:

Integer i = 0;
i += 1;
System.out.println(i);

...但在底层,Java 会自动对. 进行装箱和拆箱Integer,因为该+=运算符仅适用于原始类型。它之所以有效,是因为我们明确指出数字是 a Integer,但它不适用于 a Number,因为 Java 需要确切知道它正在处理的数字类型以执行装箱/拆箱。

于 2012-01-22T00:41:39.057 回答
2

您需要将数字转换为原始类型,然后算术运算符才能工作。您会注意到Number确实有doubleValue,intValue等....

或者,您可以转换为,并使用在该类上定义BigDecimal的算术方法(不是、等,而是、等......)。这种方法会更准确(如果您需要最佳准确度,请使用),因为浮点数和双精度数仅表示一组离散的数值。请记住,BigDecimal 是不可变的,因此您始终需要将操作的结果分配给引用。+-addmultiplyBigDecimal

于 2012-01-22T00:34:37.877 回答
1

我想这就是你想要的

public synchronized average() {  
    double ret = new double[queue[0].length];  
    for (int i = 0; i < ret.length; ++i) {  
        for (int j = 0; j < size; ++j) {  
            ret[i] += queue[j][i];  
        }  
        ret[i] /= size;  
    }  
    return ret;  
}
于 2012-01-22T01:18:26.320 回答
0

可悲的是,你不能。算术运算符仅适用于原始类型(这要归功于其包装器上的自动装箱和自动拆箱)。您必须为需要该方法处理的所有原始类型覆盖给定的方法,就像在许多 JDK 类中所做的那样。

于 2012-01-22T00:37:57.457 回答
0

由于每个可能的byte, short, char, int, float,double都可以表示为double它更有效(因为它是一个原语而不是任何对象)并且使用起来更简单, 如果您需要准确的或 BigDecimal 或 BigInteger double,您将需要特定的类型。Numberlong

于 2012-01-22T08:55:42.947 回答
0

在 Java 中,算术运算符仅适用于原始类型。这里的问题是 Java 具有这些原始类型的类表示,并且从一个到另一个的切换通常是隐式的,通过称为autoboxing的特性。

在这种情况下,您将需要为您需要的算术运算类型实现方法,可能必须为每个操作传入的每个可能的数字类型创建重载方法

于 2012-01-22T00:47:29.963 回答
-1
public int showAllNum(Number i, Number j) {
    return (int) (i.doubleValue()+j.doubleValue()); 
}
于 2018-06-15T16:17:24.753 回答