13

我试图在java中掌握溢出和下溢异常,但找不到任何好的教程。具体我想学

  1. 它们彼此有何不同?
  2. 这些异常的子类是什么?
  3. 他们在哪种情况下被抛出?
  4. 其中哪些可以处理,如何处理?
  5. 与它们相关的最佳实践是什么?

任何指向有用教程的链接都可以

4

4 回答 4

30

好的,OP谈到想知道堆栈溢出和算术溢出,以及它们相应的下溢。开始....

  1. 当数字太大而无法容纳其值类型时,就会发生算术溢出。例如,anint保存介于 -2 31和 2 31 -1 之间的值,包括这两个值。如果您的号码超过这些限制,则会发生溢出,并且号码会“环绕”。这些不会导致在 Java 中生成异常。
  2. 当浮点数变得太小而无法很好地区分零(数字的精度被截断)时,就会发生算术下溢。在 Java 中,这些也不会导致异常。
  3. 当你调用一个函数,调用另一个函数,然后调用另一个,然后另一个......并且函数调用堆栈变得太深时,就会发生堆栈溢出。当这种情况发生时,你会得到一个StackOverflowError
  4. Java 中不会发生堆栈下溢。它的运行时系统应该防止这种事情发生。

要回答 OP 的其他问题(请参阅评论),当您超出数组的边界时,IndexOutOfBoundsException会发出 an 。

于 2010-01-28T13:39:47.050 回答
7

在 Java 算术中,溢出或下溢永远不会抛出异常。相反,对于浮点运算,该值设置为Not a number“无限”或零。

要测试这些,您可以使用静态方法:isNaNisInfinite使用适当的包装类。您可以酌情处理。例子:

double d1 = 100 / 0.;
if (Double.isNaN(d1)) {
    throw new RuntimeException("d1 is not a number");
}
if (Double.isInfinite(d1)) {
    throw new RuntimeException("d1 is infinite");
}

对于某些操作,您可以获得ArithmeticException,例如dividing by zero在整数数学中。

我刚刚问了一个有关处理此问题的完整项目样式方法的相关问题。

于 2010-01-28T13:34:04.880 回答
0

Java 没有无符号整数。如果您认为它可能有用,这使得抛出异常变得容易。

public class Counter
{
  private int counter = 0;

  public int increment ()
  {
    counter += 1;
    if (counter < 0)
      throw new RuntimeException ("Counter overflow");
    else
      return counter;
  }

  public String toString() { return String.valueOf(counter); }
}
于 2013-11-20T13:18:25.867 回答
0

由于这是一个非常古老的问题,应该注意的是,从 Java 8 开始,Math 包提供了“精确”的算术方法,这些方法将在发生溢出时触发异常。

例如

int iv1 = Integer.MAX_VALUE;
int iv2 = Math.addExact(iv1,1);

会触发 java.lang.ArithmeticException: integer overflow 。

于 2021-03-08T11:56:54.723 回答