如何添加两个java.lang.Numbers?

我有两个数字。 例如:

Number a = 2; Number b = 3; //Following is an error: Number c = a + b; 

为什么在数字上不支持算术运算? 无论如何,我将如何在java中添加这两个数字? (当然我从某个地方得到他们,我不知道他们是整数或浮动等)。

你说你不知道你的数字是整数还是浮点数…当你使用Number类的时候,编译器也不知道你的数字是整数,浮点数还是其他的东西。 结果,像+和 – 这样的基本math运算符不起作用; 电脑将不知道如何处理这些值。

开始编辑

基于讨论,我认为一个例子可能会有所帮助。 计算机将浮点数存储为两部分,一个系数和一个指数。 所以在一个理论体系中,001110可能分解为0011 10或者3 2 = 9,但是正整数将二进制数字存储起来,所以001110也可以表示2 + 4 + 8 = 14。你告诉计算机你不知道这个数字是一个浮点数还是一个整数或者是什么,所以它知道它有001110,但是不知道这个数字是9还是14或者其他值。

结束编辑

你可以做的是做一个小小的假设,并转换成mathtypes之一。 所以你可以有

 Number c = a.intValue() + b.intValue(); 

你可能会变成

 Integer c = a.intValue() + b.intValue(); 

如果你愿意承受一些舍入错误,或者

 Float c = a.floatValue() + b.floatValue(); 

如果你怀疑你没有处理整数,并且可能存在小的精度问题。 或者,如果你宁愿采取一个小小的performance而不是那个错误,

 BigDecimal c = new BigDecimal(a.floatValue()).add(new BigDecimal(b.floatValue())); 

这也将工作,使一个方法来处理你的添加。 现在我不知道这会造成的性能影响,但我认为它会比使用BigDecimalless。

 public static Number addNumbers(Number a, Number b) { if(a instanceof Double || b instanceof Double) { return new Double(a.doubleValue() + b.doubleValue()); } else if(a instanceof Float || b instanceof Float) { return new Float(a.floatValue() + b.floatValue()); } else if(a instanceof Long || b instanceof Long) { return new Long(a.longValue() + b.longValue()); } else { return new Integer(a.intValue() + b.intValue()); } } 

正确添加任何两种types的java.lang.Number的唯一方法是:

 Number a = 2f; // Foat Number b = 3d; // Double Number c = new BigDecimal( a.toString() ).add( new BigDecimal( b.toString() ) ); 

这甚至适用于两个不同数字types的参数。 只要数字types的toString()不会降低精度,它将(应该)不会产生像溢出或失去精度的副作用。

java.lang.Number只是原始types的所有包装类的超类(参见java doc )。 为你的目的使用合适的原始types( doubleint等),或者使用相应的包装类( DoubleInteger等)。

考虑这个:

 Number a = 1.5; // Actually Java creates a double and boxes it into a Double object Number b = 1; // Same here for int -> Integer boxed // What should the result be? If Number would do implicit casts, // it would behave different from what Java usually does. Number c = a + b; // Now that works, and you know at first glance what that code does. // Nice explicit casts like you usually use in Java. // The result is of course again a double that is boxed into a Double object Number d = a.doubleValue() + (double)b.intValue(); 

使用以下内容:

 Number c = a.intValue() + b.intValue(); // Number is an object and not a primitive data type. 

要么:

 int a = 2; int b = 3; int c = 2 + 3; 

我认为你的问题有两个方面。

为什么运营商+号码不支持?

因为Java语言规范。 没有指定这个,并且没有操作符重载。 也没有编译时自然的方法来将数字转换为某种基本types,并且没有自然增加来定义某种types的操作。

为什么在数字上不支持基本的算术运算?

(从我的评论复制:)

并不是所有的子类都可以用你期望的方式实现它。 特别是对于primefacestypes,很难定义一个有用的合同,例如添加。

此外,如果您尝试将“长”添加到“短”,则添加方法会很麻烦。

Number是一个你不能创build实例的abstract类。 如果你有一个正确的实例,你可以得到number.intValue()number.intValue()并添加它们。

首先,你应该知道Number是一个抽象类。 这里发生的是,当你创build2和3时,它们被解释为原语,在这种情况下创build一个子types(我认为是一个整数)。 因为Integer是Number的子types,所以可以将新创build​​的Integer分配给Number引用。

但是,一个数字只是一个抽象。 它可以是整数,也可以是浮点数等,所以math运算的语义是不明确的。

数字不提供经典的地图操作有两个原因:

首先,Java中的成员方法不能是运算符。 这不是C ++。 充其量,他们可以提供一个add()

其次,当你有两个input时(例如,用一个int分隔一个浮点数),搞清楚什么types的操作是非常复杂的。

相反,您有责任将转换回到您感兴趣的特定原始types,并应用math运算符。

最好的答案是使用双重调度钻取到大多数已知types的util(看看Smalltalk的addtition实现)