小程式:方法swap交換字串a和b指向的示例,為什么沒有交換成功?
public static void swap1(String a,String b) {//交換a和b
String temp=b;
b=a;
a=temp;
System.out.println(a+" "+b);//輸出B A
}
public static void swap2(String[] s) {
String temp=s[0];
s[0]=s[1];
s[1]=temp;
}
public static void main(String[] args) {
String a="A";
String b="B";
String[] s= {"1","2"};
swap1(a, b);
swap2(s);
System.out.println(a+" "+b); //這里為什么輸出A B?String類是final型別的參考資料型別,方法swap1難道不是傳遞參考?為何不輸出B A ?
System.out.println(s[0]+" "+s[1]); //輸出2 1,這里我能理解
}
uj5u.com熱心網友回復:
陣列變數s 參考 {“1”,“2”}陣列物件,方法swap2是參考傳遞,書上說String也是參考資料型別,變數a 參考 “A”字串物件,變數b參考“B”字串物件,swap1也該是參考傳遞啊,但是輸出卻不是這樣的,是我哪里沒整對?。uj5u.com熱心網友回復:
在參考型別作為引數進行傳遞時,此時傳遞的是地址值副本,但是這兩個地址指向同一個地方。在副本地址沒有進行更改指向時,對副本地址指向的資料進行操作會影響到原始資料的值String是特殊的,他是final修飾,它的底層是一個final 型的ch[]陣列,它是不可變的。每次你對它進行更改其實是將它引向了新物件,它原地址的值是不可更改的
uj5u.com熱心網友回復:
可參考這篇文章https://www.cnblogs.com/jagh/p/jjjj.htmluj5u.com熱心網友回復:
就像獨孤九劍的總決式:java在方法傳遞引數時,是將變數復制一份,然后傳入方法體去執行。簡單分析下:
1、String a="A";——>jvm在堆中開辟一塊記憶體heap1,存值"A",在堆疊中分配給a一個記憶體stack1,stack1中存放heap1的地址
2、swap1(a,b);——>jvm復制一份a,叫a2,并且分配了一個記憶體stack2,存的也是heap1的地址,將a2傳入方法swap1
3、在方法中其實是對a2進行操作,所以在方法中列印出來的其實是a2
4、方法結束后,方法外列印a,由于存放的是heap1的地址,所以還是A
String b="B";同理
uj5u.com熱心網友回復:
String比較特殊,不能這樣交換。考慮使用StringBuffer作為引數。uj5u.com熱心網友回復:
把你的代碼改下,就可以產生你要的結果public static void swap1(String a,String b) {//交換a和b
String temp=b.intern();
b=a.intern();
a=temp;
System.out.println(a+" "+b);//輸出B A
}
uj5u.com熱心網友回復:
4樓說得很明白了。uj5u.com熱心網友回復:
你好,我能理解你的分析。照此分析,交換String[] s={1,2},swap2(String[] s),在方法體內是操作副本s',故在方法體中列印s':2 1。
然而回到main,s應該還是原來的{1,2},但結果又不對
uj5u.com熱心網友回復:
方法體內正確,但是main方法列印結果還是A B。
uj5u.com熱心網友回復:
簡單點,對于String是不可能通過改變“形參”來改變的,因為String是不可變的,你只能改變參考地址
uj5u.com熱心網友回復:
就像獨孤九劍的總決式:java在方法傳遞引數時,是將變數復制一份,然后傳入方法體去執行。
簡單分析下:
1、String a="A";——>jvm在堆中開辟一塊記憶體heap1,存值"A",在堆疊中分配給a一個記憶體stack1,stack1中存放heap1的地址
2、swap1(a,b);——>jvm復制一份a,叫a2,并且分配了一個記憶體stack2,存的也是heap1的地址,將a2傳入方法swap1
3、在方法中其實是對a2進行操作,所以在方法中列印出來的其實是a2
4、方法結束后,方法外列印a,由于存放的是heap1的地址,所以還是A
String b="B";同理
public static void changeString(String a) {
a=new String("after");
}
public static void changeArray(String[] s) {
s[0]=new String("after");
}
public static void main(String[] args) {
String a="before";
String[] s= {"before"};
changeString(a);
changeArray(s);
System.out.println(a); //輸出 before
System.out.println(s[0]); //輸出 after,為什么?
}
uj5u.com熱心網友回復:
在參考型別作為引數進行傳遞時,此時傳遞的是地址值副本,但是這兩個地址指向同一個地方。在副本地址沒有進行更改指向時,對副本地址指向的資料進行操作會影響到原始資料的值
String是特殊的,他是final修飾,它的底層是一個final 型的ch[]陣列,它是不可變的。每次你對它進行更改其實是將它引向了新物件,它原地址的值是不可更改的
public static void changeString(String a) {
a=new String("after");
}
public static void changeArray(String[] s) {
s[0]=new String("after");
}
public static void main(String[] args) {
String a="before";
String[] s= {"before"};
changeString(a);
changeArray(s);
System.out.println(a); //輸出 before
System.out.println(s[0]); //輸出 after,為什么?
}
uj5u.com熱心網友回復:
String比較特殊,不能這樣交換。考慮使用StringBuffer作為引數。
public static void changeString(String a) {
a=new String("after");
}
public static void changeArray(String[] s) {
s[0]=new String("after");
}
public static void main(String[] args) {
String a="before";
String[] s= {"before"};
changeString(a);
changeArray(s);
System.out.println(a); //輸出 before
System.out.println(s[0]); //輸出 after,為什么?
}
uj5u.com熱心網友回復:
太深層的原因沒有考慮清楚,但很明顯String 對應的內容是因為記憶體地址變化的原因。有可能是因為 A \ B 字串都在常量池,參考直接對接常量池;而陣列存放在方法區,陣列變數參考方法區的陣列物件,陣列物件在參考常量池的 字串。
public static String changeString(String ax) {
ax=new String("after");
return ax;
}
public static String[] changeArray(String[] sx) {
sx[0]=new String("after");
return sx;
}
public static void main(String[] args) {
String a="before";
String[] s= {"before"};
String ax = changeString(a);
String[] sx = changeArray(s);
System.out.println(a); //輸出 before
System.out.println(a==ax); //輸出 false
System.out.println(s[0]); //輸出 after,為什么?
System.out.println(s==sx); //輸出true
}
uj5u.com熱心網友回復:
String比較特殊,不能這樣交換。考慮使用StringBuffer作為引數。
public static void changeString(String a) {
a=new String("after");
}
public static void changeArray(String[] s) {
s[0]=new String("after");
}
public static void main(String[] args) {
String a="before";
String[] s= {"before"};
changeString(a);
changeArray(s);
System.out.println(a); //輸出 before
System.out.println(s[0]); //輸出 after,為什么?
}
草率了,JAVA只能值傳遞,參考型別也不能交換變數句柄,但物件的內容是可以改變的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/225642.html
標籤:Java SE
上一篇:論Python和Java?
下一篇:代碼是給人讀的,不是拿來炫技的
