介紹
眾所周知,Java是一種物件導向的程式語言。也就是基本概念,因為 說基礎的基礎就是一切都是物件。物件是使用類別來描述的。
反過來,類別也有狀態和行為。例如,銀行帳戶可能具有帳戶中金額形式的狀態,並具有增加和減少餘額的行為。Java 中的行為是使用方法來實現的。如何描述方法是在 Java 學習之旅的一開始就介紹的。例如Oracle的官方教學:「
定義方法」。這裡有兩個重要的面向:
- 每個方法都有一個簽名。簽名由方法名稱及其輸入參數組成;
- 方法必須指定返回類型;
- 傳回類型不是方法簽名的一部分。
同樣,這是 Java 是強類型語言這一事實的結果,編譯器希望提前了解盡可能多的地方使用了哪些類型。再次,保護我們免受錯誤的影響。總的來說,一切都是為了好的。嗯,在我看來,這再次向我們灌輸了處理數據的文化。因此,對於方法,值類型是指定的。若要從方法傳回相同的值,請使用關鍵字
return
。
Java中的關鍵字return語句
statements 關鍵字
return
指的是“控制流語句”,如 oracle 教程“
控制流語句”中討論的那樣。您也可以在官方教學中閱讀如何傳回值:「
Returning a Value from a Method」。編譯器會盡其所能仔細監視方法傳回的值是否與該方法指定的回傳值類型相符。讓我們使用教程點的
線上 IDE作為範例。我們來看原來的例子:
public class HelloWorld {
public static void main(String []args) {
System.out.println("Hello World");
}
}
我們可以看到,這裡執行了一個方法
main
,這是程式的入口點。程式碼行是從上到下執行的。我們的
main
方法不能傳回值,否則我們會收到錯誤:「
Error: Main method must return a value of type void
」。因此,該方法將簡單地輸出到螢幕。現在讓我們將字串的接收轉移到一個單獨的方法來接收訊息:
public class HelloWorld {
public static void main(String []args) {
System.out.println(getHelloMessage());
}
public static String getHelloMessage() {
return "Hello World";
}
}
正如我們所看到的,使用關鍵字
return
我們指定了返回值,我們稍後在方法中使用它
println
。在方法的描述(定義)中,
getHelloMessage
我們表明它將傳回 us
String
。這允許編譯器檢查方法的操作是否與其聲明的方式一致。當然,方法定義中指定的傳回值的類型可以比程式碼傳回值的類型更廣泛,即 最主要的是類型彼此減少。否則我們會得到一個編譯時錯誤:「
error: incompatible types
」。順便說一句,問題可能立即出現:為什麼
return
它適用於程式流程控制運算子?但因為它會打亂程式從上到下的正常流程。例如:
public class HelloWorld {
public static void main(String []args){
if (args.length == 0) {
return;
}
for (String arg : args) {
System.out.println(arg);
}
}
}
main
從範例中可以看出,如果我們的java程式不帶參數調用, 我們就會中斷方法的執行。請務必記住,如果您
return
擁有該代碼,則該代碼將無法存取。我們的智慧編譯器會注意到這一點,並且不會允許您執行這樣的程式。例如,以下程式碼將無法編譯:
public static void main(String []args) {
System.out.println("1");
return;
System.out.println("2");
}
有一個骯髒的黑客可以解決這個問題。例如,出於調試目的或出於某些其他原因。可以透過將上面的程式碼包裝
return
在
if
區塊中來修復:
if (2==2) {
return;
}
錯誤處理中的回傳語句
有一個非常棘手的情況 - 我們可以將它
return
與錯誤處理結合使用。我想說的是,
return
在
catch
區塊中使用它是非常非常糟糕的形式,所以你應該避免它。但我們需要一個例子,對吧?他在這裡:
public class HelloWorld {
public static void main(String []args) {
System.out.println("Value is: " + getIntValue());
}
public static int getIntValue() {
int value = 1;
try {
System.out.println("Something terrible happens");
throw new Exception();
} catch (Exception e) {
System.out.println("Catched value: " + value);
return value;
} finally {
value++;
System.out.println("New value: " + value);
}
}
}
乍一看,似乎應該返回2,因為
finally
它總是被執行。但不會,該值將為 1,並且對變數 in 的更改
finally
將被忽略。此外,如果它
value
包含一個物件並且我們
finally
說
value = null
,那麼它
catch
仍然會傳回對該物件的引用,而不是
null
。但從區塊來看,
finally
操作員
return
會正常運作。同事們顯然不會感謝你送這樣的禮物。
無效類
最後。你可以寫出一個奇怪的結構,例如
void.class
. 看起來,為什麼以及有什麼意義呢?事實上,在使用
Java Reflection API的各種框架和棘手的情況下,這可能是非常必要的。例如,您可以檢查方法傳回的類型:
import java.lang.reflect.Method;
public class HelloWorld {
public void getVoidValue() {
}
public static void main(String[] args) {
for (Method method : HelloWorld.class.getDeclaredMethods()) {
System.out.println(method.getReturnType() == void.class);
}
}
}
這在需要替換方法的真實程式碼的測試框架中非常有用。但要做到這一點,您需要了解該方法的行為方式(即它會傳回哪種類型)。還有第二種方法可以實作
main
上面程式碼中的方法:
public static void main (String[] args) {
for (Method method : HelloWorld.class.getDeclaredMethods()) {
System.out.println(method.getReturnType() == Void.TYPE);
}
}
關於它們之間差異的相當有趣的討論可以在 stackoverflow 上閱讀:
What is the Difference Between java.lang.Void and void? #維亞切斯拉夫
GO TO FULL VERSION