1. 程式人生 > 其它 >Java形參、實參、值傳遞、引用傳遞

Java形參、實參、值傳遞、引用傳遞

轉載於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) { int
a = 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
我們來分析下為什麼了??