在下面的源代码中,我正在重新抛出 Exception
。
为什么不需要在方法的签名上加上throws
关键字?
public void throwsOrNotThrowsThatsTheQuestion() {
try {
// Any processing
} catch (Exception e) {
throw e;
}
}
最佳答案
这种行为似乎只发生在 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>
...直到我在 try
block 中实际抛出 Exception
:
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 已经足够智能,可以通过分析 try
block 代码来检测可能引发的 Exception
(s) 类型,而 1.6 刚刚看到throw e;
类型 Exception
并为此给出错误。
将其更改为抛出 RuntimeException
使其按预期编译,因为与往常一样,未经检查的 Exception
不需要 throws
子句:
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 引入 more inclusive type checking .引用...
Consider the following example:
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;
}
}
This examples's try block could throw either FirstException or SecondException. Suppose you want to specify these exception types in the throws clause of the rethrowException method declaration. In releases prior to Java SE 7, you cannot do so. Because the exception parameter of the catch clause, e, is type Exception, and the catch block rethrows the exception parameter e, you can only specify the exception type Exception in the throws clause of the rethrowException method declaration.
However, in Java SE 7, you can specify the exception types FirstException and SecondException in the throws clause in the rethrowException method declaration. The Java SE 7 compiler can determine that the exception thrown by the statement throw e must have come from the try block, and the only exceptions thrown by the try block can be FirstException and SecondException. Even though the exception parameter of the catch clause, e, is type Exception, the compiler can determine that it is an instance of either FirstException or SecondException:
(强调我的)
public void rethrowException(String exceptionName)
throws FirstException, SecondException {
try {
// ...
}
catch (Exception e) {
throw e;
}
}
关于java - 重新抛出异常 : Why does the method compile without a throws clause?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19913834/