此行为似乎仅发生在 Java 1.7 上。当使用 1.6 进行编译时,我收到以下编译器错误消息:
c:\dev\src\misc>javac -source 1.6 Main.java
warning: [options] bootstrap class path not set in conjunction with -source 1.6
Main.java:22: error: unreported exception Exception; must be caught or declared
to be thrown
throw e;
^
1 error
1 warning
但在 Java 1.7 中,它可以编译。
c:\dev\src\misc>javac -source 1.7 Main.java
c:\dev\src\misc>
...直到我真正抛出一个Exception
in the try
block:
public static void throwsOrNotThrowsThatsTheQuestion() {
try {
// Any processing
throw new IOException("Fake!");
} catch (Exception e) {
throw e;
}
正在编译...
c:\dev\src\misc>javac -source 1.7 Main.java
Main.java:22: error: unreported exception IOException; must be caught or declare
d to be thrown
throw e;
^
1 error
看起来 Java 1.7 已经足够聪明,可以检测到这种类型Exception
(s) 可能会通过分析抛出try
块代码,如 1.6 刚刚看到的throw e;
类型的Exception
并为此给出了一个错误。
将其更改为抛出RuntimeException
使其按预期编译,因为一如既往,未经检查Exception
不需要throws
clause:
public static void throwsOrNotThrowsThatsTheQuestion() {
try {
// Any processing
throw new RuntimeException("Fake!");
} catch (Exception e) {
throw e;
}
正在编译...
c:\dev\src\misc>javac -source 1.7 Main.java
c:\dev\src\misc>
说明
这是发生的事情:
Java 7 推出更具包容性的类型检查。引用...
考虑以下示例:
static class FirstException extends Exception { }
static class SecondException extends Exception { }
public void rethrowException(String exceptionName) throws Exception {
try {
if (exceptionName.equals("First")) {
throw new FirstException();
} else {
throw new SecondException();
}
} catch (Exception e) {
throw e;
}
}
此示例的 try 块可能会抛出 FirstException 或 SecondException。假设您要在 rethrowException 方法声明的 throws 子句中指定这些异常类型。在 Java SE 7 之前的版本中,您不能这样做。因为catch子句的异常参数e是Exception类型,并且catch块重新抛出异常参数e,所以只能在rethrowException方法声明的throws子句中指定异常类型Exception。
然而,在 Java SE 7 中,您可以在 rethrowException 方法声明的 throws 子句中指定异常类型 FirstException 和 SecondException。 Java SE 7 编译器可以确定语句 throw e 抛出的异常一定来自于 try 块,而 try 块抛出的异常只能是 FirstException 和 SecondException。即使 catch 子句的异常参数 e 是 Exception 类型,编译器也可以确定它是 FirstException 或 SecondException 的实例:
(强调我的)
public void rethrowException(String exceptionName)
throws FirstException, SecondException {
try {
// ...
}
catch (Exception e) {
throw e;
}
}