Java7-带最后一个异常的精确重播

Java7-带最后一个异常的精确重播,java,exception,final,java-7,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) {

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

//(如果没有最终版本,就不能用Java编译它仍然是有效的Java。你只是失去了它“精确”的好处。

我相信我看到了Josh Bloch的推特,说“最终”限制已经取消了。我会看看是否能找到一篇关于它的帖子,但我怀疑这只是“早期”而已您阅读的文档现在不准确

编辑:我找不到确切的“it's changed”贴子,但显示了一个示例,它不是final。它讨论了当catch块声明多个类型时,异常变量隐式final,但这有点不同


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

这两种编译的原因是,uni-catch子句中未随后修改的异常是隐式final()

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

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;
    }
}
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
    }
}

我认为您缺少test2()的抛出异常位-更精确,因此“抛出异常”通常会失败。相关:Hey@jon skeet,我知道这是一篇+1年前的文章,但最后一次编辑中有一点:在这种情况下,如果未声明
e
final
,编译器不会隐式地将其视为
final
(如在多重捕获中)。但是,如果
e
引用被更改,那么
异常
必须包含在
抛出
子句中。@Betomentejo BullsEye。