关于Java 7:Java 7 – 使用最终异常进行精确重新抛出

Java 7 - Precise rethrow with a final Exception

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

例如:

1
2
3
4
5
6
7
8
9
10
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中,如果声明异常EDCX1,则可以更精确地抛出异常:0:

1
2
3
4
5
6
7
8
9
10
11
//(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;
    }
}

我的问题:医生说我需要宣布例外情况。但是如果我不这样做,上面的代码仍然可以编译和工作。我错过什么了吗?

参考文献:

投币项目:多捕集和最终回注
添加对rethrown异常更灵活的检查


我相信我看到乔什·布洛赫在推特上说"最终"限制已经被取消了。我会看看是否能找到一篇关于它的文章,但我怀疑你读到的任何"早期"文档现在都不准确。

编辑:我找不到确切的"它被改变"的帖子,但是Java 7文档状态显示了一个例子,它不是最终的。它谈到了当catch块声明多个类型时,异常变量是隐式最终的,但这是稍微分开的。

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


这两种编译的原因是,uni catch子句中的一个异常(随后未进行修改)是隐式的最终异常(jls 14.20)。

因此,对于不编译的示例,您需要以某种方式修改e,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
    }
}


没有最终结果,它仍然是有效的Java。你只是失去了"精确"的好处。