這是一個人為的例子。我有一個非 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?
}
uj5u.com熱心網友回復:
拋出例外會中斷控制流,立即退出該方法。拋出例外時不需要回傳值,因為呼叫該方法的代碼沒有正常完成。例如,在下面的代碼中,不需要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不需要提供回傳值。
事實上,一個方法不能既回傳一個值又拋出一個例外,因為回傳一個值意味著該方法正常完成。
uj5u.com熱心網友回復:
沒有實際要求回傳值的方法包含 return 陳述句。也許令人驚訝的是,這段代碼是合法的:
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 節)中拋出例外。顯式 throw (§14.18) 陳述句也會導致例外。例外會導致控制轉移,這可能會阻止陳述句的正常完成。
所以:要求是方法不能正常完成;兩者return并throw是導致法正常完成的方式。
請注意,這并不是說該方法必須例外完成,而是回傳到開始時的 while 回圈示例,這不會正常或例外完成:因為回圈條件是常量 true,并且不包含 return 、 throw 或 break 或可能引發例外的陳述句,該回圈永遠不會完成,這也很好(至少從語言的角度來看)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/379802.html
