開門見山:Java中只有值傳遞!
一、錯誤認知
基本類型是值傳遞,對象類型是引用傳遞。
二、形參與實參
1. 形式參數(shù)
方法中聲明的用于接收的參數(shù)。
2. 實際參數(shù)
調(diào)用方法時傳遞的參數(shù)。
三、值傳遞與引用傳遞
1. 值傳遞(創(chuàng)建副本)
指將實參copy一份,賦給形參。修改形參時,不改變原本實參的值。
2. 引用傳遞(不創(chuàng)建副本)
指將地址直接傳給形參。修改形參時,改變原本實參的值。
四、三段代碼解釋
1. 基本變量值傳遞
public static void main(String[] args) {
int i = 10;
pass(i );//在pass方法中輸出一次
System.out.println(i);//i=10,pass方法結(jié)束后輸出一次
}
public void pass(int j) {
j = 20;
System.out.println(j);//j=20
}
從代碼中可以看到,i與j結(jié)果不同,是因為i傳給j時,創(chuàng)建了一個副本給j,修改j時,跟i沒關(guān)系。
2. User對象值傳遞
public static void main(String[] args) {
User a= new User();
a.setName("小龍女");
pass(a);
System.out.println(a);//第二次輸出,user.name = '楊過'
}
public void pass(User user) {
user.setName("楊過");
System.out.println(user);//第一次輸出,user.name = '楊過'
}
- 以上代碼有人可能就有疑問了,不是說值傳遞嗎,為什么形參地址的變量的“值”改變了,實參地址的變量的“值”也會改變呢?
- 注意,我這里說的是形參地址——的變量——的值改變。
- 回顧一下值傳遞的定義:
指將實參copy一份,賦給形參。修改形參時,不改變原本實參的值。
而我們這里改變的不是形參,而是形參所指的對象的值。 - 所以我們認為,pass(a),其實傳的是地址(這個地址也是值傳遞)。
3. 如果還是有疑問,請看下面
public static void main(String[] args) {
User a= new User();
a.setName("小龍女");
pass(a);
System.out.println(a);//第二次輸出,user.name = '小龍女'
}
public void pass(User user) {
user = new user();
user.setName("楊過");
System.out.println(user);//第一次輸出,user.name = '楊過'
}
- 咦,為什么只是多了一行user = new user();就截然不同了呢?
- 因為這里,在值傳遞時,pass方法中new了一個新的對象,這個對象的地址與原本實參不一樣。并把新的地址給了user。
- 如果此時是引用傳遞,那么原本對象a的地址是不是也該變?yōu)樾聦ο蟮牡刂?。但是實際沒有。因此證明形式參數(shù)user也是一個創(chuàng)建了副本的。而創(chuàng)建副本的就是值傳遞。