为什么,在Java算法中,溢出或下溢永远不会抛出exception?

在Java算术运算期间,JVM不会抛出下溢或溢出exception。 很多时候,我们遇到意想不到的结果,并想知道出了什么问题。

在.NET技术的情况下,我们有溢出和Undeflowexception。

所以我的问题是,为什么Java设计不会在算术运算期间抛出此exception

这可能是多种因素的组合:

  1. Java之前的大语言使用未经检查的算术。 容易出现数值溢出的众所周知的算法倾向于在不依赖于检查算术的情况下解释潜在的溢出。
  2. 经过检查的算术会在大量使用算术指令的算法中引入显着的开销,这会使Java处于显着的劣势,特别是对于基准测试而言。
  3. 一些算法依赖于静默数值上溢/下溢。 如果检查算术运算,重写这些算法很快就会变得非常重要。
  4. 检查算术不是确保内存安全所必需的(与其他JVM检查相反,如空指针和数组边界)。

.NET虚拟执行环境(现在是ECMA-335标准的一部分)为已检查和未检查的算法引入了单独的指令,使其能够独立地解决使用现代托管语言的开发人员的性能和安全问题。

Indoknight说,这可能与性能有关。 Java提供了处理溢出的工具,所以如果你需要检测它,你就可以做到。 你也有long和BigInteger,可以使用它们来避免你的int溢出。

你应该从stackoverflow中的类似问题看到这个答案。 Java如何处理整数下溢和溢出以及如何检查它?

Java基于C和C ++,它基于Assembly。 在这些语言中都没有抛出exception,部分原因是在设计算术运算时,exception不在那些语言中。

首先使用较大的类型(如longdoubleBigIntegerBigDecimal更安全,如果您确定这是不合适的,则只使用较小的类型。

如果您使用这些更宽泛的类型,它不一定是常见问题。

最初创建Java时,语言设计者就是这样做的。 我不确定为什么,但如果有它肯定会在提高例外方面有性能损失。

“语言设计人员的教训是,可能值得减少静默溢出的可能性。这可以通过提供对不会无声溢出的算术的支持来完成。程序可以抛出exception而不是溢出,就像Ada一样,或者他们可以Lisp也会根据需要自动切换到更大的内部表示,Lisp也是如此。这两种方法都可能会产生与之相关的性能损失。降低静默溢出可能性的另一种方法是支持目标类型,但这会增加型号系统[Modula-3 1.4.8]。“

礼貌–Jackhua Bloch和Neal Gafter的Java益智游戏陷阱和陷阱