当抛出异常时会发生什么?

6

我遇到了一个问题,不理解异常抛出时会发生什么。

抛出的异常会被如何处理?是什么处理它以确保程序不崩溃?

例如,在这篇教程中的示例中,谁将处理抛出的ArithmeticException

static int remainder(int dividend, int divisor)
    throws DivideByZeroException {
    try {
        return dividend % divisor;
    }
    catch (ArithmeticException e) {
        throw new DivideByZeroException();
    }
}
1个回答

6
您链接的教程强调了Java中异常类型的重要区别,即异常是可检查的还是不可检查的可检查的异常需要您作为开发人员捕获它(即处理它),或声明它被抛出并在上游处理。预期您可以从这些异常中恢复。 不可检查的异常可能会在应用程序的自然执行过程中出现,可能没有自然的方式让应用程序恢复。通常不鼓励捕获它们,因为这往往表明设计不良(例如允许零进入除法运算,这是非法参数!)。
在此场景中,因为方法remainder声明它正在抛出DivideByZeroException,所以它的所有上游调用者都必须通过以下方式处理其异常:
public static void main(String[] args) {
    try {
        NitPickyMath.remainder(1, 0);
    } catch (DivideByZeroException e) {
        e.printStackTrace();
    }
}

...或通过:

public static void main(String[] args) throws DivideByZeroException {
   NitPickyMath.remainder(1, 0);
}

后面的内容翻译如下:

后一种形式的警告是,没有任何东西会处理异常,这将导致应用程序崩溃。


...那么谁来处理抛出的ArithmeticException异常呢?

通过将其放置在catch块中,您已经在处理它。您只是重新抛出一个已检查的异常来处理由将1除以0导致的实际错误。


感谢您详细的回复,非常感激。所以基本上唯一处理异常的方法就是确保它在 catch 块中被捕获?即使它被捕获了,也不意味着在打印堆栈跟踪后应用程序不会崩溃吗? - rni902
1
@rni902:...或者在方法签名中声明它被抛出。这是处理已检查异常的唯二方式。(如果您不这样做,编译器消息会说“几乎”相同的内容。)至于在打印堆栈跟踪后崩溃的问题:如果您没有捕获任何异常,那么它将崩溃;如果您只在捕获异常之后打印堆栈跟踪,则不会崩溃。 - Makoto
谢谢,我想问的是,当它被捕获时会发生什么?即“在幕后”。这就是我不理解的地方。 - rni902

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接