Java 7 - 精确重新抛出最终异常

时间:2011-07-31 11:46:20

标签: java exception final java-7

在以前的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

3 个答案:

答案 0 :(得分:24)

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

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

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

答案 1 :(得分:4)

两个编译的原因是,未随后修改的uni catch子句中的异常是隐式最终的(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 :(得分:0)

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