gst*_*low 8 java exception try-catch unreachable-code
研究方法如下:
static private void foo() {
try {
throw new FileNotFoundException();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
尽管最后一个catch块实际上无法访问,但此代码编译良好.
现在让评论 throw new FileNotFoundException();行
执行:
哎呀!我们看
Unreachable catch block for FileNotFoundException. This exception is never thrown from the try statement body
Run Code Online (Sandbox Code Playgroud)
奇怪.为什么java在这些情境中使用双重标准?
static private void foo(FileNotFoundException f) {
try {
throw f;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
工作以及构造函数调用
我注意到在不同版本的java编译器上,我看到编译此代码的不同结果.
public class RethowTest {
public static void main(String[] args) {
try {
throw new FileNotFoundException();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
throw e;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的本地电脑上:java 1.7.0_45 -
C:\Program Files\Java\jdk1.7.0_45\bin>javac D:\DNN-Project\DNN-Project\src\main\java\exceptionsAndAssertions\RethowTest.java
D:\DNN-Project\DNN-Project\src\main\java\exceptionsAndAssertions\RethowTest.java:15: warning: unreachable catch clause
} catch (IOException e) {
^
thrown type FileNotFoundException has already been caught
1 warning
Run Code Online (Sandbox Code Playgroud)
java 1.6.0_38
D:\DNN-Project\DNN-Project\src\main\java\exceptionsAndAssertions\RethowTest.java:16: unreported exception java.io.IOException; must be caught or declared to be thrown
throw e;
^
1 error
Run Code Online (Sandbox Code Playgroud)
http://www.compileonline.com/compile_java_online.php(Javac 1.7.0_09) -
HelloWorld.java:9: warning: unreachable catch clause
} catch (IOException e) {
^
thrown type FileNotFoundException has already been caught
1 warning
Run Code Online (Sandbox Code Playgroud)
可访问性规则在Java 8 JLS 14.21(和Java 7)中定义如下:
如果满足以下两个条件,则可以访问catch块C:
C参数的类型是未经检查的异常类型或Exception或Exception的超类,或者try块中的某些表达式或throw语句是可到达的,并且可以抛出一个已检查的异常,其类型可分配给C的参数类型.(如果包含它的最内层语句可以访问,则表达式是可到达的.)
正常和突然完成表达式见§15.6.
try语句中没有先前的catch块,因此C的参数类型与A参数类型的子类相同.
请注意,规则不要禁止您的示例代码.第二个捕获块不符合第二个要点的标准.
(在示例的原始版本中,您抓住了Exception.可达性推理会有所不同,但答案是相同的 - 有效代码.)
这是不一致的吗?举个例子,你可以说是这样的.
他们为什么不在可达性规则中解决这个问题呢?我不知道.你需要问Java设计师!! 然而:
为了解决这个问题,可达性规则的制定需要更加复杂.规范中的额外(不必要的?)复杂性是一个问题.
你可以说这种不一致并没有破坏任何东西.可达性规则实际上只是一种在用户代码中发现潜在错误的方法.它不涉及类型安全或可预测的执行; 即会破坏Java运行时语义的东西.
如果他们现在改变了规范,那将使一小部分有效和有效的Java程序无效.鉴于稳定性是Java的主要卖点之一,这不是一个好主意.
在另一方面,我想不出一个技术原因,他们不可能都在规范解决了这个"矛盾".
您注意到某些Java编译器在第二天发出警告消息catch.那没问题.允许Java编译器为(技术上)合法的Java代码提供警告.
如果它们是错误,那在技术上就是编译器错误...根据我对JLS的阅读.
Pet*_*der -3
如果实例化,new FileNotFoundException()则调用 Class 的构造函数FileNotFoundException。在这个构造函数中,理论上可以通过调用本机方法来抛出 IOException fillInStackTrace- 编译器可能不知道构造函数的内容是什么,也许IOException会抛出一个异常。
请参阅这篇文章: https: //community.oracle.com/thread/1445008? start=0 的示例。
FileNotFoundException()如果编译器在每次出现时都会检查构造函数:这会导致 Java 对性能的忽视。
| 归档时间: |
|
| 查看次数: |
6573 次 |
| 最近记录: |