Java 引數傳遞是值傳遞還是引用傳遞?
首先把結論表明,Java 的引數傳遞是值傳遞,因為有部分細節讓人引起誤解以為是引用傳遞,故我們寫兩個例子來舉例探討。
public class ExampleUnitTest { @Test public void addition_isCorrect() { assertEquals(4, 2 + 2); int a = 10; System.out.print(a+"\n"); add(a); System.out.print(a+"\n"); } private void add(int b) { b = 15; System.out.print(b+"\n"); } }
控制檯輸出為
int 屬於基本資料型別,我們都知道基本資料型別儲存於棧,而它的地址就是值本身,這個例子中我們把 a 的值複製一份傳遞給 add 方法中,形參 b 被賦值 15,當 add 方法執行完最後一行程式碼,整個方法棧被回收。
public class ExampleUnitTest { @Test public void addition_isCorrect() { assertEquals(4, 2 + 2); Student a = new Student(10, "小明"); System.out.print("地址為 " + a + "\n age " + a.age + "\n name" + a.name); change(a); System.out.print("\n地址為 " + a + "\n age " + a.age + "\n name" + a.name); } private void change(Student b) { b.age = 1000; b.name = "滅霸"; Student c = new Student(12, "小黑"); b = c; System.out.print("\n地址為 " + b + "\n age " + b.age + "\n name" + b.name); } private static class Student { private int age; private String name; public Student(int age, String name) { this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } } }
控制檯輸出為
地址為 demo.rzj.com.androiddemo.ExampleUnitTest$Student@1a93a7ca age 10 name小明 地址為 demo.rzj.com.androiddemo.ExampleUnitTest$Student@3d82c5f3 age 12 name小黑 地址為 demo.rzj.com.androiddemo.ExampleUnitTest$Student@1a93a7ca age 1000 name滅霸
相信大部分同學對於Java 是值傳遞最大的疑問就是為什麼這個例子中的 Student 例項物件 a 傳遞到 change 方法中 age 、name 引數被改變了會影響到外面的物件,大家先看一下控制檯的輸出,當我們對形參 b = c 時,它的記憶體地址確實是改變了,但是並沒有影響到外面的 a 物件的記憶體地址,這就充分說明了值傳遞,只不過值得一提的是,這個值傳遞是複製了一份物件,但是裡面的引數所引用的地址指向是一樣的,重點理解的是引用資料型別傳遞的確實是值,但是物件內部的引數指向的是一樣的資料。