为什么Java Number数据类型不会溢出?

为什么java Number / Numeric数据类型如(Integer / Long / …)不会抛出溢出exception? 例如:我们在数学上得到了错误的答案

Integer val = Integer.MAX_VALUE * 2; System.out.println("Max val unexpected" + val); 

**最大值意外-2 **

我知道; 这些数据类型的核心使用原始java数据类型。 仍然,通过抛出像.ValueOverflowException之类的东西来防止错误答案不是一个好主意。 考虑扩展和添加此行为,但这些所有类都是最终的..

请发表您的想法和意见。

这些类型只是原始类型的包装器,因此如果它们的行为不同则会出乎意料。 这些类型不抛出这些exception的一个原因是,如果执行这样的检查将会非常昂贵,并且处理器上的这些整数类型在溢出时不会触发中断(相反,浮点类型可以触发中断)各种活动)。 如果您希望支持任意精度,那么您可能对BigInteger类型感兴趣。

数据类型确实溢出,您的示例certificate了这一点。 他们不做的是在溢出时抛出exception。

在Java中,通常必须声明exception,并且必须捕获它。 是的,在某些情况下,这种情况并不成立(错误,运行时exception等),但这些规则对于exception的大多数都很快。

如果您想要MathOverflowException,那么您需要捕获它。 否则它就没有用处。 这意味着你需要编写看起来像这样的代码

 try { int x = 5 + 7; } catch (MathOverflowException e) { // do something } 

现在这是真正令人讨厌的地方。 什么“抛出”exception? 它必须是“加号”,对吧? 好吧,只有一点。 对象上的方法抛出exception,这意味着加号必须是“对象”5上的“方法”。除了在这个特殊的数学情形中,你不要取消引用对象的方法; 否则它看起来像:

 try { int x = 5.+ 7; // Note the dot-plus ".+" } catch (MathOverflowException e) { // do something } 

但是如果你开始这样做,那么你需要操作括号。

 try { int x = 5.+(7); } catch (MathOverflowException e) { // do something } 

这样做意味着赋值“等号”也是一种方法。

 try { int x.=(5.+(7)); } catch (MathOverflowException e) { // do something } 

但是我们没有创建一个“新的”x,所以它需要是:

 try { (new int x()).=(5.+(7)); } catch (MathOverflowException e) { // do something } 

或者可能

 try { new int x(5).+(7); } catch (MathOverflowException e) { // do something } 

无论哪种方式,它都与简单的代数风格相差甚远,Java决定保留众所周知的代数/ C-ish / Fortran-ish语法。 在这样做的过程中,他们很快发现他们需要制作隐藏的“幕后”规则以支持面向对象的方式支持数学语法,或者他们只需要放弃他们的数学是面向对象的假装。 他们选择后者。

这就是规范说它有效的方式。 有关详细信息,请参阅4.2 – Java规范中的原始类型和值 。