繁体   English   中英

可以使用已检查的异常抛出未检查的异常吗?

[英]Can a checked exception be used to throw an unchecked exception?

我正在运行以下代码:

import java.io.FileNotFoundException;
import java.io.IOException;

class Basic1 {
    int c;

    void calculation(int a, int b) throws Exception {
        c = a / b;
    }
}

class Basic extends Basic1 {
    void calculation(int a, int b) throws IOException {
        c = a / b;
        RuntimeException ae = new ArithmeticException();
        throw ae;
    }

    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        int c;
        Basic ba = new Basic();
        try {
            ba.calculation(a, b);
        } catch (IOException e) {
            System.out.println("Zero can't be there in the denominator. : IoException");
        } catch (ArithmeticException e) {
            System.out.println("Zero can't be there in the denominator. : Arthimetic Exception");
        } catch (Exception e) {
            System.out.println("Zero can't be there in the denominator. : Exception");
        }
    }
}

程序编译成功并输出“分母中不能有零。:算术异常”(输出如预期)。

我的问题是程序如何能够成功编译? 为什么我在创建RuntimeException对象时在calculation()抛出IOException时没有收到错误?

我的第二个问题是程序进入catch (ArithmeticException e)子句,编译器是否在运行时决定执行哪个catch 我理解正确吗?

对于您的第一个问题,使用throws E (其中E是一些任意检查的异常)构造的方法不必抛出任何内容。 这意味着任何调用您的方法的人都必须能够处理E ,这允许您的方法在不处理它的情况下抛出E 否则这将是一个编译错误。 通常,您的方法的文档会指定何时抛出E 用 JLS 的话来说:

本质上,对于可能由方法体或构造函数的执行导致的每个已检查异常,除非在方法声明的 throws 子句中提及其异常类型或其异常类型的超类型,否则会发生编译时错误或构造函数。

这并不是说您必须在方法主体中抛出给定的已检查异常。 请注意,您可以对未经检查的异常使用throws ,但这对程序没有影响,因为未经检查的异常可能会在任何地方抛出而无需处理。 这就是他们的重点。

在您的代码中,您抛出一个RuntimeException 根据定义,任何扩展RuntimeException类(包括它自己)都是未经检查的。 ArithmeticException就是其中之一,因此您可以将其分配给RuntimeException类型的变量,然后将其抛出,而无需在throws子句中指定它。

对于您的第二个问题,我假设编译器不会优化掉各种catch子句。 在这种情况下,不,执行的catch不是在编译时确定的。 当您的程序中抛出任何异常时,它会向上传播堆栈直到被捕获。 如果不是,它会停止执行并将堆栈跟踪打印到System.err 由于抛出ArithmeticException ,第一个catch子句不匹配,但第二个匹配,因此被执行。 第三个( catch (Exception e) )将匹配,但顺序与catch子句有关,并且只执行一个,因此此处不执行该子句。

但是,在这种情况下,编译器优化掉您的catch子句并将程序直接定向到catch (ArithmeticException e)子句中的代码并非不可想象,因为您的方法将始终抛出ArithmeticException 然而,必须考虑到,任何一行代码都可能抛出一些模糊的错误,比如OutOfMemoryError 编译器在优化时必须考虑到这种边缘情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM