为什么方法在引发异常后不需要返回值?



这是一个精心设计的例子。我有一个非void方法,它抛出了一个异常。为什么我以后不必返回一个值呢?毕竟,该方法是非空的。

public static Toast makeText(Context context, CharSequence text, int duration) {
throw new RuntimeException("Stub!");
//Must return something from here but there is not, Why?
}

抛出异常会中断控制流,并立即从方法中退出。当抛出异常时,不需要返回值,因为调用方法的代码不能正常完成。例如,在以下代码中,foo不需要返回数字,因为int x = foo();没有成功,而是传播异常:

int foo() {
throw new RuntimeException();
}
void bar() {
int x = foo();
// This line will not be reached
System.out.println(x);
}

由于int x = foo();之后的代码无论如何都不会被执行,所以x不需要从foo接收返回值,因此foo不需要提供返回值。

事实上,一个方法不能既返回值又抛出异常,因为返回值意味着该方法正常完成。

返回值的方法不需要包含返回语句。也许令人惊讶的是,这个代码是合法的:

int noReturn() {
while (true) {}
}

语言规范的关键是JLS 8.4.7,它说:

如果一个方法被声明为具有返回类型(§8.4.5(,那么如果该方法的主体可以正常完成,则会发生编译时错误(§14.1(

"正常完成";如JLS 14.1:所述

每个语句都有一个正常的执行模式,其中执行某些计算步骤。以下部分描述了每种语句的正常执行模式。

如果所有步骤都按照描述进行,没有突然完成的迹象,则声明正常完成。但是,某些事件可能会阻止语句正常完成:

  • break、yield、continue和return语句(§14.15、§14.21、§14.16、§14.17(导致控制权转移,可能会阻止包含它们的表达式、语句和块的正常完成
  • 某些表达式的求值可能会引发Java虚拟机的异常(§15.6(。显式抛出(§14.18(语句也会导致异常。异常会导致控制权的转移,这可能会阻止语句的正常完成

因此:要求该方法不能正常完成;并且CCD_ 7和CCD_。


注意,这并不是说该方法必须异常完成:返回到开头的while循环示例,该示例不会正常或异常完成:因为循环条件是常量true,不包含return、throw或break,也不包含可能引发异常的语句,所以该循环永远不会完成,这也很好(至少从语言的角度来看(。

最新更新