Java形參、實參、值傳遞、引用傳遞
阿新 • • 發佈:2021-08-23
轉載於https://www.cnblogs.com/wudiffs/p/11573314.html——原作者:wudiffs
一、形參
形參:用來接收呼叫方法時傳遞的引數,只有在被呼叫時才分配記憶體,一旦呼叫結束,就釋放記憶體空間。因此僅在方法內有效。
public void swap(int a, int b) { int temp = a; a = b; b = temp; }
這裡a,b就是形參,方法結束時,在棧空間就會被銷燬。
二、實參
呼叫上面方法swap(6, 8); 其中6 8就是實參。
三、值傳遞和引用傳遞
- 值傳遞:方法呼叫時,實際引數將它的值傳遞給形式引數,函式就收到的是原始值的副本,此時記憶體中存在兩個相同的基本型別,若方法中對形參執行處理操作,並不會影響實際引數的值。
- 引用傳遞:方法呼叫時,實際引數的引用(指記憶體地址,不是引數的值)被傳遞給方法中相應的形式引數,函式接受到的是原始值的記憶體地址,在方法中,形參和實參的內容(地址)相同,方法中對形參的處理會影響實參的值。
public class People { private String name; private String age; public People(String name, String age) { this.name = name; this.age = age; } public String getName() {return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } } public class Base1 { public static void main(String[] args) { inta = 10; // 按值傳遞 test1(a); System.out.println("main a==" + a); People p = new People("rose", "18"); // 按引用傳遞 test2(p); System.out.println("main name==" + p.getName() +", age==" + p.getAge()); } public static void test1(int a) { a = 20; System.out.println("test1 a==" + a); } public static void test2(People p) { p.setName("jack"); p.setAge("19"); System.out.println("test2 name==" + p.getName() +", age==" + p.getAge()); } }
輸出結果: test1 a==20 main a==10 test2 name==jack, age==19 main name==jack, age==19
結論:
- 形參為基本型別時,對形參的處理不會影響實參。
- 形參為應用型別時,對形參的處理會影響實參。
- String、Integer、Double等immutable型別,因為本身沒有提供修改函式的操作,每次操作都是生成一個新物件,所以要特殊對待,可以理解為值傳遞,形參操作不會影響實參物件。
四、java物件及引用
以上面的People為例,構建一個物件:People p1 = new People("jack", "19");
其實這個物件包含四個動作。
- 右邊的new People,是以People類為模板,在堆空間建立一個People類物件。
- 末尾的("jack", "19"),指的是物件建立後,呼叫的建構函式,對剛生成的物件進行初始化。
- 左邊的People p1建立了一個People類引用變數,所謂People類引用,就是以後可以用來指向People物件的引用。
- = 操作符使物件引用指向剛建立的People物件。
People p1; p1 = new People("jack", "19"); 上面兩條語句等價於 People p1 = new People("jack", "19");
這樣看就很明白,一個是物件應用變數,一個是物件實體。
如果只執行第一條,還沒執行第二條此時建立的p1還沒指向任何一個物件,它的值是null。
再來一句: People p2; p2 = p1; 這裡發生了複製行為,物件本身沒有複製,被複制的只是物件的引用。結果是p2也指向了p1的物件。
再來一句: p2 = new People("rose", "18"); 此時p2指向了第二個物件,此時得出結論: 一個物件引用可以指向0個或者1個物件。 一個物件可以有N個引用指向它。
再來一句: p1 = p2; 此時p1指向p2這個物件,至於之前的p1這個物件,它已成為垃圾回收機制的處理物件。
五、java中方法引數的引用傳遞
“當一個物件被當作引數傳遞到一個方法”,這就是所謂的引用傳遞。
public class Base2 { public static void main(String[] args) { People p = new People("jordon","23"); // changePeople1(p); changePeople2(p); System.out.println(p.getName() + "===" + p.getAge()); } public static void changePeople1(People p) { p.setName("kobe"); p.setAge("24"); } public static void changePeople2(People p) { p.setName("kobe"); p.setAge("24"); p = new People("james", "24"); } } 以上程式碼呼叫changePeople1和changePeople2都是輸出 kobe===24 我們來分析下為什麼了??