方法的實參和形參

墨澜發表於2024-07-31

值傳遞


"值傳遞"(Pass by Value)是指在呼叫方法時,將引數的值複製並傳遞給方法中的形參。這意味著方法接收的是原始資料的一個副本,而不是原始資料本身。以下是值傳遞的一些關鍵特點:

  1. 資料複製:當呼叫方法時,引數的值被複制到新記憶體區域(方法的棧空間)的形參中。

  2. 獨立性:方法內的形參和方法外的實參在記憶體中是獨立的。方法對形參的修改不會影響到實參。

  3. 基本資料型別:對於Java等語言中的原始資料型別(如int, double, char等),總是透過值傳遞。

  4. 不可變性:由於基本型別的不可變性,方法內對引數值的修改實際上並不改變原始資料。

  5. 記憶體效率:對於大型物件或陣列,值傳遞可能意味著複製大量資料,這可能不是最記憶體效率的方式。

  6. 物件引用:對於物件引用型別,值傳遞的是引用的副本,而不是物件本身。這意味著兩個引用指向同一個物件,但副本引用和原始引用是獨立的,改變副本引用不會影響原始引用。

  7. 副作用:值傳遞不保證方法內部對引數的修改對外部可見,除非引數本身是一個物件,並且方法修改了物件的內部狀態。

示例:

public class PassByValueExample {
    public static void main(String[] args) {
        int a = 10;
        modifyValue(a);
        System.out.println("Outside method: " + a); // 輸出不會改變,仍然是 10
    }

    public static void modifyValue(int value) {
        value = 20; // 僅修改了傳入的副本,不影響原始變數
    }
}

示例解釋:

  • main 方法中,我們有一個原始資料型別 int a,其值為 10。
  • 呼叫 modifyValue 方法,並傳遞 a 作為引數。
  • modifyValue 方法內,我們嘗試修改引數 value 的值為 20。但這只是修改了 value 的副本,原始變數 a 的值不會改變。
  • 列印 a 的值,輸出結果仍然是 10,表明方法內的修改沒有影響外部的 a

值傳遞是大多數程式語言在引數傳遞時採用的機制,它有助於保護原始資料不被方法內部的修改影響。然而,對於物件引用,需要理解傳遞的是引用的副本,而不是實際的物件本身。

引用轉遞


引用傳遞(Pass by Reference)是指在呼叫方法時,傳遞的是物件的引用(或地址),而不是物件本身的複製。這意味著方法接收的是原始物件的引用,因此方法內部對物件所做的任何修改都會影響到原始物件。

引用傳遞的特點:

  1. 傳遞引用:方法接收的是物件引用的副本,但這個副本指向的是同一個物件。
  2. 共享物件:方法內對物件的修改會反映到原始物件上,因為它們共享同一個物件。
  3. 修改可見:方法內部對物件屬性的修改在方法外部是可見的。
  4. 物件不變:物件本身不會被複制,只有引用被傳遞,因此節省記憶體。
  5. 基本資料型別:對於基本資料型別(如 int, double 等),大多數語言(包括Java)實際上是透過值傳遞。
  6. 物件型別:對於物件型別,傳遞的是引用的副本,但兩個引用指向同一個物件。

示例:

public class PassByReferenceExample {
    public static void main(String[] args) {
        Person person = new Person("Alice", 30);
        modifyPerson(person);
        System.out.println("Outside method: " + person.getName() + ", " + person.getAge());
    }

    public static void modifyPerson(Person p) {
        p.setName("Bob"); // 修改物件的屬性
        p.setAge(40); // 修改物件的屬性
    }

    static class Person {
        private String name;
        private int age;

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }
    }
}

示例解釋:

  • main 方法中,建立了一個 Person 物件 person
  • 呼叫 modifyPerson 方法,並傳遞 person 作為引數。
  • modifyPerson 方法內,修改了傳入物件 pnameage 屬性。
  • 這些修改會影響原始物件 person,因為 p 是對原始物件引用的副本。
  • 列印 person 的資訊,輸出結果將反映方法內的修改:"Outside method: Bob, 40"。

注意:

  • 在Java中,所有的引數傳遞都是透過值傳遞,包括物件的引用。因此,有時人們可能會混淆“引用傳遞”和“值傳遞”的概念。
  • 當你傳遞一個物件的引用時,你實際上是傳遞了這個引用的副本,但這個副本指向同一個物件。因此,任何透過這個副本引用對物件所做的修改都會反映到原始物件上。

相關文章