Tah*_*ami 4 java return exception
这是一个人为的例子。我有一个非 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?
}
Run Code Online (Sandbox Code Playgroud)
抛出异常会中断控制流,立即退出该方法。当抛出异常时,不需要返回值,因为调用该方法的代码无法正常完成。例如,在以下代码中,不需要foo返回数字,因为int x = foo();不成功,而是传播异常:
int foo() {
throw new RuntimeException();
}
void bar() {
int x = foo();
// This line will not be reached
System.out.println(x);
}
Run Code Online (Sandbox Code Playgroud)
由于后面的代码int x = foo();无论如何都不会被执行,因此不需要x从 接收返回值foo,因此foo不需要提供返回值。
事实上,一个方法不能既返回值又抛出异常,因为返回值意味着该方法正常完成。
返回值的方法没有实际要求包含 return 语句。也许令人惊讶的是,这段代码是合法的:
\nint noReturn() {\n while (true) {}\n}\nRun Code Online (Sandbox Code Playgroud)\n语言规范的关键是JLS 8.4.7,其中表示:
\n\n\n如果某个方法被声明为具有返回类型 (\xc2\xa78.4.5),那么如果该方法的主体可以正常完成 (\xc2\xa714.1),则会发生编译时错误。
\n
JLS 14.1中描述了“正常完成” :
\n\n\n每个语句都有一个正常的执行模式,其中执行某些计算步骤。以下部分描述了每种语句的正常执行模式。
\n如果所有步骤都按照描述执行,并且没有突然完成的迹象,则该语句被认为正常完成。但是,某些事件可能会阻止语句正常完成:
\n\n
\n- Break、yield、Continue 和 return 语句(\xc2\xa714.15、\xc2\xa714.21、\xc2\xa714.16、\xc2\xa714.17)会导致控制权转移,从而可能阻止正常完成表达式、语句和包含它们的块。
\n- 对某些表达式的求值可能会引发 Java 虚拟机 (\xc2\xa715.6) 的异常。显式的 throw (\xc2\xa714.18) 语句也会导致异常。异常会导致控制权转移,从而可能阻止语句的正常完成。
\n
所以:要求是该方法不能正常完成;和return都是throw导致该方法异常完成的方法。
请注意,这并不是说该方法必须异常完成:而是返回到开始时的 while 循环示例,这不会正常完成或异常完成:因为循环条件是常量 true,并且不会包含返回、抛出或中断,或者可能引发异常的语句,该循环永远不会完成,这也很好(至少从语言的角度来看)。
\n