简体   繁体   English

为什么即使我总是抛出Exception,我也需要在Java方法中返回一个值?

[英]Why do I need to return a value in a Java method, even if I always throw an Exception?

Why doesn't the following code compile: 为什么以下代码无法编译:

    @Test
public boolean testException() throws MyException {
    try {
        System.out.println("Try some resource, which may throw an exception");
        return resource.getSomething();
    } catch (Exception e) {
        logAndThrowSpecificException(e);
    } finally {
        System.out.println("Clean up");
    }
}

private void logAndThrowSpecificException(Exception e) throws MyException {
    throw new MyException("Checked exception", e);
}

In IntelliJ it complains that I need to return a value from the last line of the testException() method, but as far as I can see there is no code path that will get to that point? 在IntelliJ中,它抱怨我需要从testException()方法的最后一行返回一个值,但是据我所知,没有代码路径可以到达那一点? What am I missing? 我想念什么?

There are similar questions on StackOverflow , but the best resolution I could find was to just put in a return null statement. 在StackOverflow上也有类似的问题 ,但我能找到的最佳解决方案是只将return null语句放入。 There was no proper answer to why this was necessary. 没有正确答案说明为什么这样做是必要的。

我怀疑它不确定是否logAndThrowSpecificException()会始终抛出logAndThrowSpecificException()异常,即使它的用途很明确,也可能导致testException()的结尾。

[...] as far as I can see there is no code path that will get to that point? [...] 据我所知,没有代码路径可以到达那一点? What am I missing? 我想念什么?

There is, in general, no way to tell if a certain path is possible or not (standard result, follows immediately from the halting problem). 通常,没有办法确定某条路径是否可行(标准结果是从暂停问题中得出的)。

Due to this, the compiler won't put much effort into analyzing such things. 因此,编译器不会花费太多精力来分析这些东西。 In fact it won't even bother looking outside the method currently being compiled, which is why you get the error in this case. 实际上,它甚至不会打扰当前正在编译的方法,这就是为什么在这种情况下会出现错误的原因。

The specifics of what is regarded as reachable code is specified in the Java Language Specification in Section 14.21 Unreachable Statements . Java语言规范的第14.21节“无法到达的语句”中指定了可到达的代码的详细信息。 In fact, it would be a direct violation of the specification if a compiler compiled the code you provided. 实际上,如果编译器编译了您提供的代码,将直接违反规范

Even though it seems obvious that logAndTrowSpecificException always throws an exception, the compiler can't know that for certain. 即使logAndTrowSpecificException似乎总是抛出异常,编译器也无法肯定地知道这一点。 It is possible to instrument the class at load time and replace the implementation of the method with one that does not (always) throw an exception. 可以在加载时检测该类,并用不会(始终)引发异常的方法替换该方法的实现。

Keyword: aspect oriented programming. 关键字:面向方面的编程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM