方法的形參和實參

HvitAska發表於2024-08-01

方法的形參和實參

在Java中,方法的形參(Formal Parameter)和實參(Actual Parameter)是呼叫方法時引數傳遞的兩個關鍵概念。

形參(Formal Parameter)

  1. 定義:形參是在方法宣告中指定的引數,用於接收呼叫方法時傳遞的值。形參相當於是方法內部的區域性變數。
  2. 作用:形參為方法提供了一個或多個輸入的佔位符,允許方法接收外部資料。
  3. 特點
    • 形參的型別和數量必須與呼叫方法時提供的實參匹配。
    • 形參僅在方法被呼叫時存在,呼叫結束後,形參所佔用的記憶體會被釋放。

實參(Actual Parameter)

  1. 定義:實參是在呼叫方法時實際傳遞給方法的值或變數。
  2. 作用:實參用於初始化形參,將資料傳遞給方法。
  3. 特點
    • 實參可以是常量、變數、表示式或任何可以求值的結果。
    • 實參的個數和型別必須與方法定義中的形參列表一致。
    • 實參的求值順序對方法呼叫的結果沒有影響,因為引數是透過值傳遞的。

呼叫方法時的引數傳遞

當呼叫一個方法時,實參的值會被複制到形參中。這個過程稱為“按值傳遞”(Pass by Value)。這意味著:

  • 如果實參是一個基本資料型別(如int、double等),則傳遞的是實際的值。
  • 如果實參是一個物件引用,傳遞的是引用的副本,但副本指向同一個物件。

示例

public class Example {
    // 方法宣告,包含兩個形參
    public void printInfo(int id, String name) {
        System.out.println("ID: " + id + ", Name: " + name);
    }

    public static void main(String[] args) {
        Example ex = new Example();
        
        // 呼叫方法,傳遞實參
        int studentId = 1;
        String studentName = "John Doe";
        ex.printInfo(studentId, studentName);
    }
}

在這個例子中:

  • printInfo 方法有兩個形參:int idString name

  • main 方法中,我們建立了兩個變數 studentIdstudentName 作為實參。

  • 當呼叫 ex.printInfo(studentId, studentName); 時,studentIdstudentName 的值被複制到 printInfo 方法的形參中。

  • 形參是方法定義的一部分,用於接收呼叫時傳遞的資料。

  • 實參是呼叫方法時實際傳遞的資料。

  • Java方法呼叫是按值傳遞的,這意味著基本資料型別的值會被複制,而物件引用的副本會指向同一個物件。

在Java中,方法引數的傳遞機制通常被稱為“值傳遞”,但這個術語可能會引起一些混淆,因為它與“引用傳遞”的概念有關。為了澄清這一點,讓我們詳細解釋這兩個概念:

值傳遞(Pass by Value)

  1. 定義在Java中,所有方法呼叫都是透過值傳遞的。這意味著當一個方法被呼叫時,實際上傳遞的是引數值的複製。
  2. 作用:值傳遞確保了方法內部對引數的修改不會影響到原始的引數值。
  3. 特點
    • 對於基本資料型別(如intdoublechar等),當方法被呼叫時,會建立一個新的數值副本,方法內部對這些數值的操作不會影響原始變數。
    • 對於物件引用,傳遞的是引用的副本,但這個副本指向同一個物件。因此,如果方法內部修改了物件的內部狀態(即物件的欄位),這些修改將反映在原始物件上。但如果方法內部嘗試重新分配引用(即讓副本指向一個新的物件),這不會改變原始引用。

引用傳遞(Pass by Reference)

  1. 概念誤解:在Java中,沒有真正的“引用傳遞”。儘管有時會這樣描述,但實際上Java總是透過值傳遞引數。

  2. 作用:當傳遞的是物件引用時,方法可以操作物件的狀態,因為所有引用副本都指向同一個物件。

  3. 特點

    • 儘管傳遞的是引用的副本,但副本和原始引用都指向堆記憶體中的同一個物件因此,對物件屬性的任何修改都會影響到原始物件。

    • 如果嘗試在方法內部重新分配引用(例如,將引數引用指向一個新的物件),這不會影響原始引用,因為只有副本被修改了。

      註釋:引用傳遞事實上只是複製了實參的地址

示例

public class Test {
    public static void main(String[] args) {
        int num = 5; // 基本資料型別
        String str = "Hello"; // 物件引用

        changeInt(num); // 呼叫方法,傳遞基本資料型別的值
        changeString(str); // 呼叫方法,傳遞物件引用的副本
    }

    public static void changeInt(int n) {
        n = 10; // 修改副本,不影響原始變數
    }

    public static void changeString(String s) {
        s = "World"; // 重新分配引用,不影響原始引用
        s.toUpperCase(); // 修改物件狀態,影響原始物件
    }
}

在這個例子中:

  • changeInt 方法嘗試修改傳遞的整數,但由於是值傳遞,原始變數 num 不受影響。
  • changeString 方法首先嚐試重新分配引用 s,這不會影響原始引用 str。然後呼叫 toUpperCase() 方法修改了字串物件的狀態,這影響了原始物件,因為所有引用(包括原始引用)都指向同一個物件。

總結

  • Java總是透過值傳遞引數,無論是基本資料型別還是物件引用。
  • 對於基本資料型別,方法內部的修改不會影響到原始變數。
  • 對於物件引用,方法可以修改物件的狀態,但重新分配引用隻影響副本,不影響原始引用。

相關文章