9

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

而在 .NET 技术的情况下,我们有溢出和 Undeflow 异常。

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

4

4 回答 4

6

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

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

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

于 2013-04-18T15:36:04.637 回答
2

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

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

于 2013-04-18T14:28:20.880 回答
1

最初创建 Java 时,语言设计者就是这样做的。我不确定为什么,但如果有它肯定会在引发异常时降低性能。

“语言设计者的教训是,降低静默溢出的可能性可能是值得的。这可以通过提供对不会静默溢出的算术的支持来实现。程序可以抛出异常而不是像 Ada 那样溢出,或者它们可以根据需要自动切换到更大的内部表示以避免溢出,Lisp 也是如此。这两种方法都可能有与之相关的性能损失。减少静默溢出可能性的另一种方法是支持目标类型,但这增加了显着的复杂性类型系统 [Modula-3 1.4.8]。”

礼貌 - Joshua Bloch 和 Neal Gafter 的 Java 谜题陷阱和陷阱

于 2013-04-18T14:13:58.423 回答
1

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

首先使用较大的类型(如longordoubleBigIntegeror )要安全得多,BigDecimal如果您确实确定这是不合适的,则仅使用较小的类型。

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

于 2013-04-18T14:41:12.173 回答