【问题标题】:Why, In Java arithmetic, overflow or underflow will never throw an Exception?为什么,在 Java 算术中,溢出或下溢永远不会抛出异常?
【发布时间】:2013-04-18 14:08:42
【问题描述】:

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

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

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

【问题讨论】:

标签: java .net integer-overflow


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    您应该从 stackoverflow 中的类似问题中看到此答案。 How does Java handle integer underflows and overflows and how would you check for it?

    【讨论】:

    • +1 获取相关信息。老实说,是否应该由OP决定是否是实际答案:)
    【解决方案3】:

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

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

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

    【讨论】:

    • 当抛出溢出时,Assembly 会放置一个溢出标志。
    【解决方案4】:

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

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

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

    【讨论】:

    • 但我仍然添加了一些有用的答案。感谢您的建议,但我认为不应该投反对票。
    • 你能提供更长的书名吗?
    • 没问题,在我的回答中添加了:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多