1. 程式人生 > 實用技巧 >為什麼說Java中只有值傳遞?

為什麼說Java中只有值傳遞?

目錄

1. 方法中引數的傳遞方式

我們都知道,在呼叫一個有參方法時,會把實際引數傳遞給形式引數,而這個傳遞的過程有兩種方式,分別為值傳遞引用傳遞,它們的定義為:

  • 值傳遞:指在呼叫函式時將實際引數複製一份傳遞到函式中,這樣在函式中如果對形式引數進行修改,將不會影響到實際引數。
  • 引用傳遞:指在呼叫函式時將實際引數的地址直接傳遞到函式中,那麼在函式中對形式引數所進行的修改,將影響到實際引數。

由定義可知,值傳遞和引用傳遞的區別就在於:有沒有建立副本值傳遞建立了副本,方法體中無法改變實際引數;引用傳遞沒有建立副本,直接將實際引數的地址傳遞給了形式引數,方法體中可以改變

實際引數。

2. 為什麼說Java中只有值傳遞?

Java的資料型別分為基本型別和引用型別,很多人基於此認為:呼叫方法傳遞的引數是基本型別則為值傳遞,呼叫方法傳遞的引數是引用型別則為引用傳遞。

實際上真的如此嗎?我們來看下面的幾個例子。

當傳遞的引數為基本型別時:

public static void main(String[] args) {
    int sum = 10;
    System.out.println("修改前的sum值:"+sum);
    change(sum);
    System.out.println("修改後的sum值:"+sum);
}
public static void change(int sum) {
    sum = 20;
    System.out.println("形參num值:"+sum);
}

程式輸出結果為:

修改前的sum值:10
形參num值:20
修改後的sum值:10

由結果可知,傳遞基本資料型別時,在函式中修改的僅僅是形參,對實參的值的沒有影響。

當傳遞的引數為引用型別時:

public static void main(String[] args) {
    Person person = new Person(20, "張三");
    System.out.println("修改前:"+person);
    change(person);
    System.out.println("修改後:"+person);
}
public static void change(Person person) {
    person.setAge(30);
    person.setName("王五");
    System.out.println("形參person的值:"+person);
}

程式輸出結果為:

修改前:Person{age=20, name='張三'}
形參person的值:Person{age=30, name='王五'}
修改後:Person{age=30, name='王五'}

由輸出結果可知,實參的值竟然被改變了,那按照上面的引用傳遞的定義,實際引數的值被改變了,這不就是引用傳遞了麼?

實際上,當傳遞的引數為引用型別時,程式傳遞的不是物件本身,而是物件的引用,它的值為物件的地址。所以,當傳遞的引數為引用型別時,要判斷是否為引用傳遞,就要看傳遞的引用所指向的地址是否會被改變。

我們再來看下面的例子:

public static void main(String[] args) {
    Person person = new Person(20, "張三");
    System.out.println("修改前:"+person);
    change(person);
    System.out.println("修改後:"+person);
}
public static void change(Person person) {
	person =new Person();
    person.setAge(30);
    person.setName("王五");
    System.out.println("形參person的值:"+person);
}

為了顯示的更形象,Person物件沒有覆蓋toString方法,程式輸出的結果為:

修改前:main.test.Person@1540e19d
形參person的值:main.test.Person@677327b6
修改後:main.test.Person@1540e19d

由結果我們可以知道,person傳遞給形參的只是一個副本,在方法體裡讓形參引用新的物件,並沒有改變person的地址值,所以本質上還是值傳遞。

有個比喻很形象,你傳遞的引數只是一把鑰匙的複製品,方法拿著鑰匙進入房間的複製品,不管對房間裡的任何地方進行修改,或者修改鑰匙的複製品,鑰匙本身不會有任何改變。

所以說,Java中只有值傳遞。