有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java7精确重播,最后一个异常

在以前的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) 个答案

  1. # 1 楼答案

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

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

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

  2. # 2 楼答案

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

  3. # 3 楼答案

    这两种编译的原因都是因为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
        }
    }