java值傳遞徹底明白~
阿新 • • 發佈:2019-01-09
1、首先弄清楚一個問題:Java有沒有指標?
對於在C和C++裡頭曾經給我們帶來歡樂同時也有無限痛苦的指標,很多人寧願它再也不要出現在Java裡頭。然而事實上,Java是有指標的,Java中每個物件(除基本資料型別以外)的識別符號都屬於指標的一種。但它們的使用受到了嚴格的限制和防範,在<Thinking in Java>一書中稱它們為控制代碼。
2、傳遞控制代碼
將控制代碼傳遞進入一個方法時,指向的仍然是相同的物件。
public class Testit {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Testit a = new Testit();
a.setName("a");
Testit b = new Testit();
b.setName("b");
System.out.println("before swap: " + "a=" + a + " name: " + a.getName());
swap(a,b);
}
private static void swap(Testit swap1, Testit swap2) {
System.out.println("swaping: " + "a= " + swap1 + " name: " + swap1.getName());
Testit temp;
temp = swap1;
swap1 = swap2;
swap2 = temp;
}
}
輸出結果:
before swap: [email protected] name: a
swaping: a= [email protected] name: a
3、一個控制代碼的傳遞會使呼叫者的物件發生意外的改變。
public class Testit {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Testit a = new Testit();
a.setName("a");
Testit b = new Testit();
b.setName("b");
System.out.println("before swap: " + "a=" + a + " name: " + a.getName());
swap(a,b);
System.out.println("after swap: " + "a=" + a + " name: " + a.getName());
}
private static void swap(Testit swap1, Testit swap2) {
Testit temp;
temp = swap1;
swap1 = swap2;
swap2 = temp;
swap1.setName("a's name");
swap2.setName("b's name");
}
}
輸出結果:
before swap: [email protected] name: a
after swap: [email protected] name: b's name
我們看到,a依舊是原來那個a,但name卻不是原來那個name了!
在swap()方法中,swap1和swap2互相換過來了,這個時候swap2指向的是a,所以在setName()的時候改變的是a的name,而不是b的name。
為什麼會這樣呢?
liang_chen兄高見:Java裡的傳值實際上是拷貝引用,而不是拷貝物件。
總結:
1:對於值型別的引數來說,傳遞的是值的拷貝.
2:對於引用型別的引數來說,傳遞的是引用本身的拷貝.
所以關鍵要看你如何理解傳值中的這個“值”了。
對於在C和C++裡頭曾經給我們帶來歡樂同時也有無限痛苦的指標,很多人寧願它再也不要出現在Java裡頭。然而事實上,Java是有指標的,Java中每個物件(除基本資料型別以外)的識別符號都屬於指標的一種。但它們的使用受到了嚴格的限制和防範,在<Thinking in Java>一書中稱它們為控制代碼。
2、傳遞控制代碼
將控制代碼傳遞進入一個方法時,指向的仍然是相同的物件。
public class Testit {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Testit a = new Testit();
a.setName("a");
Testit b = new Testit();
b.setName("b");
System.out.println("before swap: " + "a=" + a + " name: " + a.getName());
swap(a,b);
}
private static void swap(Testit swap1, Testit swap2) {
System.out.println("swaping: " + "a= " + swap1 + " name: " + swap1.getName());
Testit temp;
temp = swap1;
swap1 = swap2;
swap2 = temp;
}
}
輸出結果:
before swap:
swaping: a= [email protected] name: a
3、一個控制代碼的傳遞會使呼叫者的物件發生意外的改變。
public class Testit {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Testit a = new Testit();
a.setName("a");
Testit b = new Testit();
b.setName("b");
System.out.println("before swap: " + "a=" + a + " name: " + a.getName());
swap(a,b);
System.out.println("after swap: " + "a=" + a + " name: " + a.getName());
}
private static void swap(Testit swap1, Testit swap2) {
Testit temp;
temp = swap1;
swap1 = swap2;
swap2 = temp;
swap1.setName("a's name");
swap2.setName("b's name");
}
}
輸出結果:
before swap:
after swap: [email protected] name: b's name
我們看到,a依舊是原來那個a,但name卻不是原來那個name了!
在swap()方法中,swap1和swap2互相換過來了,這個時候swap2指向的是a,所以在setName()的時候改變的是a的name,而不是b的name。
為什麼會這樣呢?
liang_chen兄高見:Java裡的傳值實際上是拷貝引用,而不是拷貝物件。
總結:
1:對於值型別的引數來說,傳遞的是值的拷貝.
2:對於引用型別的引數來說,傳遞的是引用本身的拷貝.
所以關鍵要看你如何理解傳值中的這個“值”了。