我正在创建一个类,它应该能够与任何类型的数组(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;
}
除非这不会编译,因为“Number”没有实现“+ =”或“/ =”运算符。更糟糕的是,java的Number类甚至没有实现最基本的运算符,如“+”或“ - ”!如果java不允许我编译它,我怎么能创建一个返回Numbers数组平均值的方法,因为它认为数字无法添加?!?!
答案 0 :(得分:9)
你误解了数字在Java中的工作方式。 Number
类是数字包装类的超类(Integer
,Float
等),可用于表示基本类型(int
,float
等。 )作为对象,但它不与通常的算术运算符一起工作。
如果您打算使用算术运算符,则使用基本类型。如果需要构建适用于所有数值数据类型的“通用”方法,则别无选择,只能构建同一方法的多个重载版本,每种数据类型对应一个,例如:
public float[] average(float[][] queue) {...}
public double[] average(double[][] queue) {...}
另请注意,像这样的代码适用于包装类型:
Integer i = 0;
i += 1;
System.out.println(i);
...但在幕后,Java自动boxing and unboxing Integer
,因为+=
运算符仅适用于基本类型。这是有效的,因为我们明确指出该数字是Integer
,但它不适用于Number
,因为Java需要确切地知道 类型的数字它正在处理执行装箱/拆箱。
答案 1 :(得分:1)
您需要将数字转换为基本类型,然后算术运算符才能工作。您会注意到Number
确实有doubleValue
,intValue
等等。
或者,您可以转换为BigDecimal
,并使用在该类上定义的算术方法(不是+
,-
等,但{ {1}},add
等....)此方法将更准确(如果您需要最佳准确度,请使用multiply
),因为浮点数和双精度数仅表示一组离散的数值。请记住,BigDecimals是不可变的,因此您始终需要将操作的结果分配给引用。
答案 2 :(得分: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;
}
答案 3 :(得分:0)
答案 4 :(得分:0)
在Java中,算术运算符仅适用于基本类型。这里的问题是Java具有这些原始类型的类表示,并且通过称为autoboxing的特性,从一个到另一个的切换通常是隐含的。
在这种情况下,您需要为所需的算术运算类型实现方法,可能必须为每个操作传入的每种可能的数字类型创建overloaded methods。
答案 5 :(得分:0)
由于每个可能的byte
,short
,char
,int
,float
,double
都可以表示为{{1}它更有效率(因为它是一个原语而不是任何对象)并且使用double
而不是double
更简单如果您需要准确Number
或BigDecimal或BigInteger,您将需要特定类型
答案 6 :(得分:-1)
public int showAllNum(Number i, Number j) {
return (int) (i.doubleValue()+j.doubleValue());
}