Java方法參數傳遞:值傳遞還是引用傳遞?一文搞懂

在Java學習中,“方法參數傳遞到底是值傳遞還是引用傳遞”是一個常見的困惑點。很多初學者會覺得,既然傳遞的是對象(引用類型),那就是“引用傳遞”;但實際上,Java中所有參數傳遞本質上都是值傳遞。今天我們用最簡單的例子,幫你徹底搞懂這個問題。

一、先明確概念:值傳遞 vs 引用傳遞

  • 值傳遞:方法接收的是參數的“副本”,對參數的修改不會影響原變量。比如你把一張紙條(值)遞給別人,別人寫了字,不會改變你手裏的紙條。
  • 引用傳遞:方法接收的是參數的“引用地址”(類似“鑰匙”),對參數的修改會直接影響原對象。比如你把鑰匙(引用)給別人,別人用鑰匙打開原鎖(對象)並修改內容,原鎖的內容會變。

關鍵區別:值傳遞修改的是“副本”,引用傳遞修改的是“原對象”。但Java中不存在嚴格意義的“引用傳遞”,只有“值傳遞”。

二、基本類型參數:值傳遞的直接體現

Java中的基本類型(如intdoubleboolean等)傳遞時,方法接收的是值的副本。修改參數不會影響原變量。

例子:交換兩個int變量的值

public class ValuePassDemo {
    // 定義交換方法
    public static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    }

    public static void main(String[] args) {
        int x = 10;
        int y = 20;
        swap(x, y); // 調用方法
        System.out.println("x=" + x + ", y=" + y); // 輸出:x=10, y=20
    }
}

爲什麼結果沒變?
swap方法中的abxy的“副本”。修改ab(交換)只改變了副本,原變量xy不受影響。

三、引用類型參數:容易混淆的“陷阱”

Java中的引用類型(如對象、數組、接口等)傳遞時,方法接收的是引用地址的副本。雖然修改的是“地址副本”,但由於副本和原引用指向同一個對象,因此修改對象的屬性會影響原對象

誤區1:修改對象屬性會影響原對象 → 誤認爲是“引用傳遞”

class Student {
    String name;
    public Student(String name) {
        this.name = name;
    }
}

public class ReferencePassDemo {
    // 方法:修改Student對象的name屬性
    public static void changeName(Student s) {
        s.name = "小明"; // 修改對象屬性
    }

    public static void main(String[] args) {
        Student s = new Student("小紅");
        changeName(s); // 傳遞對象引用
        System.out.println(s.name); // 輸出:小明(原對象屬性被修改)
    }
}

真相
changeName方法接收的是Student對象引用的副本(副本和原引用s指向同一個Student對象)。修改name屬性時,實際上是修改了“同一個對象”的內容,因此原對象的屬性會變。這是因爲引用地址的副本和原引用指向同一對象,而非“引用傳遞”。

誤區2:修改引用本身 → 原對象不受影響

如果在方法中修改引用本身(讓引用指向新對象),原對象不會變,這更能證明是“值傳遞”:

public static void changeReference(Student s) {
    s = new Student("小剛"); // 修改引用指向新對象
}

public static void main(String[] args) {
    Student s = new Student("小紅");
    changeReference(s); // 傳遞原引用
    System.out.println(s.name); // 輸出:小紅(原對象未被修改)
}

爲什麼結果沒變?
changeReference中的Student s是原引用的“副本”,修改副本指向新對象,原引用main中的s仍指向“小紅”。這就是值傳遞的本質:修改的是“引用地址的副本”,而非原引用本身。

四、總結:Java永遠是“值傳遞”

  • 基本類型:傳遞“值的副本”,修改副本不影響原變量。
  • 引用類型:傳遞“引用地址的副本”,修改副本指向的對象屬性會影響原對象(因爲它們指向同一對象),但修改引用本身(指向新對象)不會影響原對象。

核心結論:Java中所有參數傳遞都是值傳遞,不存在“引用傳遞”。引用類型的特殊性在於“地址副本”和“原對象共享”,而非傳遞方式本身是“引用傳遞”。

一句話記住:

  • 值傳遞:傳的是“副本”,改副本不影響原;
  • 引用類型:傳的是“地址副本”,共享對象,改屬性影響原。
    Java永遠是“值傳遞”!
小夜