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

为什么我需要在Java方法中返回一个值,即使我总是抛出一个异常?,java,exception,exception-handling,Java,Exception,Exception Handling,为什么以下代码不编译: @Test public boolean testException() throws MyException { try { System.out.println("Try some resource, which may throw an exception"); return resource.getSomething(); } catch (Exception e) { logAndThrow

为什么以下代码不编译:

    @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);
}
在IntelliJ中,它抱怨我需要从testException()方法的最后一行返回一个值,但据我所知,没有代码路径可以到达该点?我错过了什么


有,但我能找到的最好的解决方案是只输入一个returnnull语句。没有正确的答案来解释为什么这是必要的。

我怀疑它不确定
LogandRowSpecificException()
总是会抛出异常,即使它有一个非常明确的名称来说明它的用途,所以它可能会在
testException()结束时抛出异常
将被访问。

我怀疑它不确定
LogandRowSpecificException()
是否总是抛出异常,即使它有一个非常明确的名称来说明它的用途,因此有可能到达
testException()的末尾

[…]据我所知,没有任何代码路径可以达到这一点?我错过了什么

一般来说,无法判断某条路径是否可行(标准结果,从停止问题立即得出)

因此,编译器不会花费太多精力来分析这些东西。事实上,它甚至不需要查看当前正在编译的方法的外部,这就是为什么在本例中会出现错误

中的Java语言规范中指定了被视为可访问代码的细节。事实上,如果编译器编译了您提供的代码,这将直接违反规范

[…]据我所知,没有任何代码路径可以达到这一点?我错过了什么

一般来说,无法判断某条路径是否可行(标准结果,从停止问题立即得出)

因此,编译器不会花费太多精力来分析这些东西。事实上,它甚至不需要查看当前正在编译的方法的外部,这就是为什么在本例中会出现错误


中的Java语言规范中指定了被视为可访问代码的细节。事实上,如果编译器编译了您提供的代码,这将是对规范的直接违反。

即使
logandtrowsspecificeexception
似乎总是抛出异常,编译器也无法确定这一点。可以在加载时对类进行指令插入,并将方法的实现替换为不(总是)抛出异常的实现


关键词:面向方面编程。

尽管看起来很明显
logandtrowsspecificeexception
总是抛出异常,但编译器无法确定这一点。可以在加载时对类进行指令插入,并将方法的实现替换为不(总是)抛出异常的实现


关键词:面向方面编程。

FYI:Eclipse做同样的事情。FYI:Eclipse做同样的事情。它不能确定。可以插入类并将
logandRowSpecificException
的实现替换为在加载时不(总是)抛出异常的实现。关键词:面向方面编程。@user1252434谢谢,这正是我所希望的答案。虽然你应该写一个答案,这样我就可以接受这个而不是这个。我认为这将对下一个寻找相同答案的人最有帮助。@user1252434,我不确定我是否理解你的论点。听起来你是说编译器不知道
logandrowSpecificException
总是会抛出异常,因为有人可能在类编译后更改方法。我可以提供多种方法来更改字节码,使其不符合有效的Java代码。编译器在这种情况下给出错误的原因是因为规范说它应该这样做,而规范说它应该这样做是因为一般来说,没有办法解决这种类型的可达性问题。@aioobe:一般来说,一个编译函数的合法性不应取决于其他函数中存在的代码。如果可以将函数的返回类型声明为“doesntReturn”,并且如果存在未引发异常的代码执行路径,则此类函数将拒绝编译,那么编译器可以确定调用此类函数后的语句在不检查函数内的代码的情况下永远无法执行。这样一个特性可能不太难添加到语言中,但到目前为止,设计师们还认为不值得这么做。它不能确定。可以插入类并将
logandRowSpecificException
的实现替换为在加载时不(总是)抛出异常的实现。关键词:面向方面编程。@user1252434谢谢,这正是我所希望的答案。虽然你应该写一个答案,这样我就可以接受这个而不是这个。我认为这将对下一个寻找相同答案的人最有帮助。@user1252434,我不确定我是否理解你的论点。听起来你是说编译器不知道
logandrowSpecificException
总是会抛出异常,因为有人可能在类编译后更改方法。我可以提供多种方法来更改字节码,使其不符合有效的Java代码。编译器在这种情况下给出错误的原因是因为规范说它应该这样做,而规范说它应该这样做是因为一般来说,没有办法解决这种类型的可达性问题。@aioobe:一般来说,一个编译函数的合法性不应该取决于