String 是引用類型,參數傳遞是引用傳遞,但參數改變,並不影響原地址所指向的值發生變化,因為參數改變,只是改變了引用,並沒有改變傳遞進來的引用所指向的值。
轉載
首先是String。
1
|
String s =
"aaa"
;
|
這里,jvm創建一個變量引用s,在堆中創建一個對象aaa,將aaa放進常量池。s指向aaa。
然后就到了change方法里。這里這樣理解:將s引用的一個拷貝傳給方法change。這樣change有一個變量s,這個s也是指向aaa的。那么我們來通過debug來看后來發生了什么。
1.s指向aaa的時候:
2.s運行到change方法里的時候
然后看s再次賦值的時候:
然后我們運行結束change方法后到主方法里:
到這里s就結束了。那么如果我們按照傳遞的是s這個變量的引用,即String s="aaa"中這個s本身,那么,s這個本身是個變量,s指向aaa,在方法change里s又指向了123,回到主方法后s變量的指向被改變了?錯!顯然s仍舊是aaa,那么只能這樣理解:s傳遞到方法里的時候,復制了s指向的地址給change,change里的s是另一個s,s指向aaa(@718),然后在change中s又指向了123(@731),由於String是不可變類(final and Immutable),這里只是把副本s的指向修改成731,原地址718里的對象沒有發生改變因為String不可變。那么,回到主方法的時候,s變量本身沒有任何改變,s仍舊指向地址718,718的內容是aaa。所以最終打印aaa。
@Test public void testString(){ String xx = "abc"; testStr(xx); System.out.println("xx=" + xx); //xx=abc } public void testStr(String args){
System.out.println("args= " +args); //args= abc String zz = args; zz = "ghi"; System.out.println("zz= " +zz); //zz= ghi args = "wwww"; System.out.println("args2= " +args); //args2= wwww }
由上總結:String是引用數據類型,傳參數的時候,是引用傳遞,也就是傳給參數的是引用,也就是地址,參數拿到引用后,就指向了該引用在堆中所存的常量,如果此時改變參數args的值,參數會指向另外的常量地址,調用方法傳遞進來的那個變量xx引用不變,值不變,
1 String yy = new String("abc"); // 此時yy指向地址@855 2 yy = "def"; //此時指向地址@857 3 testStr(yy); 4 System.out.println("yy=" + yy); //yy=def 5 6 7 public void testStr(String args){ 8 System.out.println("args= " +args); //args= def 9 String zz = args; 10 zz = "ghi"; 11 System.out.println("zz= " +zz); //zz= ghi 12 args = "wwww"; 13 System.out.println("args2= " +args); //args2= wwww 14 }
由上總結:yy首先指向堆中855地址,這個地址里面存儲了abc,當改變yy的值為def 時,yy指向地址變了,變成了857, 而不是改變了堆中地址855所存的值;如果在第2行改為:yy="abc", yy的引用不會發生變化還是855;