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

时间:2010-12-27 06:00:26

标签: java

为什么java Number / Numeric数据类型如(Integer / Long / ...)不会抛出溢出异常? 例如:我们得到以下

的数学错误答案
Integer val = Integer.MAX_VALUE * 2;
System.out.println("Max val unexpected" + val);

** Max val unexpected-2 **

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

请发表您的想法&意见。

3 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:6)

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

在Java中,通常必须声明异常,并且这样做必须被捕获。是的,在某些情况下,这种情况并不成立(错误,运行时异常等),但这些规则对于例外情况的持续性很快。

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

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

现在这是非常讨厌的地方。什么“抛出”异常?它必须是“加号”,对吧?好吧,只有一点。对象上的方法抛出异常,这意味着加号必须是“对象”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语法。在这样做的过程中,他们很快发现要么他们需要制作隐藏的“幕后”规则以支持面向对象的方式支持数学语法,要么他们只需要放弃他们的数学是面向对象的假装。他们选择后者。

答案 2 :(得分:3)

这就是规范说它有效的方式。有关详细信息,请查看Java规范中的4.2 - Primitive Types And Values