JAVA不可达到,如果我使用多个catch块,为什么不检测到不可达的catch块?

Research following method:

static private void foo() {

try {

throw new FileNotFoundException();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

This code compiles good despite last catch block actually unreachable.

Now lets comment throw new FileNotFoundException(); row

execute:

OOOPs! we see

Unreachable catch block for FileNotFoundException. This exception is never thrown from the try statement body

Strange. Why does java use double standards for these situatons?

update for @Peter Rader

static private void foo(FileNotFoundException f) {

try {

throw f;

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

work as well as with constructor invocation

update

I noticed that on different versions of java compiler I see different result of compiling this code.

public class RethowTest {

public static void main(String[] args) {

try {

throw new FileNotFoundException();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

throw e;

}

}

}

on my local pc:

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

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

HelloWorld.java:9: warning: unreachable catch clause

} catch (IOException e) {

^

thrown type FileNotFoundException has already been caught

1 warning

解决方案

The reachability rules are defined in the Java 8 JLS 14.21 (and Java 7) as follows:

A catch block C is reachable iff both of the following are true:

Either the type of C's parameter is an unchecked exception type or Exception or a superclass of Exception, or some expression or throw statement in the try block is reachable and can throw a checked exception whose type is assignable to the type of C's parameter. (An expression is reachable iff the innermost statement containing it is reachable.)

See §15.6 for normal and abrupt completion of expressions.

There is no earlier catch block A in the try statement such that the type of C's parameter is the same as or a subclass of the type of A's parameter.

Note that the rules DO NOT forbid your example code. The second catch block does not meet the criteria of the second bullet point.

(In the original version of the example, you caught Exception. The reachability reasoning would be different, but the answer is the same - valid code.)

Is this inconsistent? For your example, you could argue that is the case.

Why didn't they address this case in the reachability rules? I don't know. You'd need to ask the Java designers!! However:

The formulation of the reachability rules would need to be significantly more complicated to handle this. Extra (unnecessary?) complexity in a specification is a concern.

You could argue that this inconsistency doesn't break anything. The reachability rules are really just a way of picking up potential errors in the users code. It doesn't involve type-safety or predictable execution; i.e. stuff that would "break" Java runtime semantics.

If they changed the spec now, that would render invalid a small proportion of valid and working Java programs. That's not a good idea, given that stability is one of the main selling points of Java.

On the other hand, I cannot think of a technical reason why they couldn't have addressed this "inconsistency" in the spec.

You noted that some Java compilers give a Warning message on the 2nd catch. That is OK. A Java compiler is allowed to give warnings for things that are (technically) legal Java code.

If they were Errors, that would technically be a compiler bug ... according to my reading of the JLS.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值