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。你只是失去了"精确"的好处。