如果我使用多个catch块,为什么java无法检测到无法到达的catch块? [英] Why java does not detect unreachable catch block if I use multiple catch blocks?

查看:478
本文介绍了如果我使用多个catch块,为什么java无法检测到无法到达的catch块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

研究以下方法:

static private void foo()  {
        try {
            throw new FileNotFoundException();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

尽管最后一个catch块实际上无法到达,但此代码仍可编译良好。

This code compiles good despite last catch block actually unreachable.

现在让注释抛出新的FileNotFoundException();

执行:

糟糕!我们看到

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

Strange抛出此异常。为什么Java对这些情况使用双重标准?

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

static private void foo(FileNotFoundException f)  {
        try {
            throw f;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

工作以及构造函数调用

我注意到在不同版本的Java编译器上,我看到了编译此代码的不同结果。

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;
            }
        }    
}

在我的本地计算机上: b $ b Java 1.7.0_45-

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

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

http://www.compileonline.com/compile_java_online.php (Javac 1.7.0_09)-

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


推荐答案

可达性规则是定义在Java 8 JLS 14.21 (和Java 7)如下:

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


只要满足以下两个条件,就可以获取catch块C:

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


  • C的参数类型是未经检查的异常类型或Exception或Exception的超类,或其中的某些表达式或throw语句尝试块我s可达并且可以抛出一个类型可以分配给C参数类型的检查异常。(如果包含表达式的最内层语句可以到达,则表达式可以到达。)

  • 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.)

有关表达式的正常和突然完成,请参见§15.6。

See §15.6 for normal and abrupt completion of expressions.

在try语句中没有较早的catch块A,因此C的参数类型与A的参数相同或相同。

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.

该规则不禁止您的示例代码。第二个catch块不符合第二个要点的条件。

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

(在示例的原始版本中,您捕获了 Exception 。可达性推理会有所不同,但答案是相同的-有效的代码。)

(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.

为什么他们没有在可达性规则中解决这种情况?我不知道。您需要询问Java设计师!!但是:

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.

您可能会说这种不一致不会破坏任何东西。可达性规则实际上只是在用户代码中拾取潜在错误的一种方式。它不涉及类型安全或可预测的执行;即会破坏 Java运行时语义的东西。

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.

如果它们现在更改了规范,将使一小部分有效且有效的Java程序无效。鉴于稳定性是Java的主要卖点之一,所以这不是一个好主意。

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.

您注意到一些Java编译器在第二个 catch 上给出警告消息。那没问题。允许Java编译器对(技术上)合法的Java代码发出警告。

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.

如果它们是错误,从技术上讲,这将是编译器错误……根据我对JLS的阅读。

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

这篇关于如果我使用多个catch块,为什么java无法检测到无法到达的catch块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆