【问题标题】:Java 7 - Precise rethrow with a final ExceptionJava 7 - 带有最终异常的精确重新抛出
【发布时间】:2011-10-16 21:14:45
【问题描述】:

在以前的java版本中,重新抛出异常被视为抛出catch参数的类型。

例如:

public static void test() throws Exception{
    DateFormat df = new SimpleDateFormat("yyyyMMdd");
    try {
        df.parse("x20110731");
        new FileReader("file.txt").read();
    } catch (Exception e) {
        System.out.println("Caught exception: " + e.getMessage());
        throw e;
    }
}

在 Java 7 中,如果您声明异常 final,则可以更准确地了解引发的异常:

//(doesn't compile in Java<7)
public static void test2() throws ParseException, IOException{
    DateFormat df = new SimpleDateFormat("yyyyMMdd");
    try {
        df.parse("x20110731");
        new FileReader("file.txt").read();
    } catch (final Exception e) {
        System.out.println("Caught exception: " + e.getMessage());
        throw e;
    }
}

我的问题:文档说我需要声明异常final。但如果我不这样做,上面的代码仍然可以编译和工作。我错过了什么吗?

参考资料:

Project Coin: multi-catch and final rethrow
Add more flexible checking for rethrown exceptions

【问题讨论】:

    标签: java exception final java-7


    【解决方案1】:

    两者都编译的原因是 uni catch 子句中的一个未随后修改的异常是隐式 final (JLS 14.20)。

    所以你的例子不能编译,你需要通过某种方式修改e,例如:

    public static void test2() throws ParseException, IOException {
        DateFormat df = new SimpleDateFormat("yyyyMMdd");
        try {
            df.parse("x20110731");
            new FileReader("file.txt").read();
        } catch (Exception e) {
            if (e instanceof ParseException) {
                e = new ParseException("Better message", 0);
            } else {
                e = new IOException("Better message");
            }
            System.out.println("Caught exception: " + e.getMessage());
            throw e; //does not compile any more
        }
    }
    

    【讨论】:

    【解决方案2】:

    相信我看到 Josh Bloch 的一条推文说“最终”限制已被取消。我会看看能不能找到一篇关于它的帖子,但我怀疑你阅读的任何“早期”文档现在都不准确。

    编辑:我找不到确切的“它已更改”帖子,但Java 7 documentation states 显示了一个示例,不是是最终的。它谈到异常变量是隐式当一个catch块声明了多个类型时,但这有点分开。

    编辑:我现在找到了我的困惑的根源,但它是一个内部邮件列表帖子 :( 无论如何,它不必被声明为 final,但我相信编译器会将其视为 隐式 final - 就像在 multi-catch 场景中一样。

    【讨论】:

    • 嘿 @jon-skeet ,我知道这是一个 +1 年的旧帖子,但在最后一次编辑中有一件事:在这种情况下,如果 e 未声明 final,则编译器 不会 隐式将其视为final(如在multi catch中)。但是,如果更改了 e 引用,则 Exception 必须包含在 throws 子句中。
    • @betomontejo BullsEye.
    【解决方案3】:

    没有final它仍然是有效的java。你只是失去了它“精确”的好处。

    【讨论】:

    • 我认为你错过了 test2() 的抛出异常位 - 它 IS 更精确,因此“抛出异常”通常会失败。
    猜你喜欢
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 2020-01-05
    • 2018-04-09
    • 1970-01-01
    • 2017-11-27
    • 2012-03-25
    相关资源
    最近更新 更多