在下面的源代码我重新抛出一个Exception.
为什么没有必要将throws关键字放在方法的签名上?
public void throwsOrNotThrowsThatsTheQuestion() {
try {
// Any processing
} catch (Exception e) {
throw e;
}
}
Run Code Online (Sandbox Code Playgroud)
rge*_*man 31
此行为似乎仅在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
Run Code Online (Sandbox Code Playgroud)
但是使用Java 1.7,它可以编译.
c:\dev\src\misc>javac -source 1.7 Main.java
c:\dev\src\misc>
Run Code Online (Sandbox Code Playgroud)
......直到我真正抛出Exception的try块:
public static void throwsOrNotThrowsThatsTheQuestion() {
try {
// Any processing
throw new IOException("Fake!");
} catch (Exception e) {
throw e;
}
Run Code Online (Sandbox Code Playgroud)
编译...
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
Run Code Online (Sandbox Code Playgroud)
看起来Java 1.7已经足够聪明Exception,可以通过分析try块代码来检测可能抛出的那种类型,其中1.6只是看到throw e;了类型Exception而且只是为了给出了错误.
更改它以RuntimeException使其按预期编译,因为一如既往,未选中的Exceptions不需要throws子句:
public static void throwsOrNotThrowsThatsTheQuestion() {
try {
// Any processing
throw new RuntimeException("Fake!");
} catch (Exception e) {
throw e;
}
Run Code Online (Sandbox Code Playgroud)
编译...
c:\dev\src\misc>javac -source 1.7 Main.java
c:\dev\src\misc>
Run Code Online (Sandbox Code Playgroud)
说明
这是发生了什么:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这个例子的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;
}
}
Run Code Online (Sandbox Code Playgroud)
java.lang.Exception是一个经过检查的异常,因此无法工作甚至编译.它可以使用unckeched(java.lang.RuntimeException).无论是否在catch块中抛出异常,绝对没有区别.
编译器错误看起来像这样(取决于编译器):
java:unreported exception java.lang.Exception; 必须被抓住或宣布被抛出
编辑:如果你从未真正抛出异常,Java 7可以处理这种情况
| 归档时间: |
|
| 查看次数: |
5454 次 |
| 最近记录: |