public void test1(){ String s = "1"; System.out.println("調用方法hange1前s的內存地址:"+System.identityHashCode(s)); Integer i = 1; System.out.println("調用方法change1前:"+s+"-----"+i); change1(s, i); System.out.println("調用方法change1后s的內存地址:"+System.identityHashCode(s)); System.out.println("調用change1方法后:"+s+"-----"+i); String[] arr = {"1","2"}; System.out.println("調用方法hange2前arr的內存地址:"+System.identityHashCode(arr)); System.out.println("調用change2方法前:"+arr[1]); change2(arr); System.out.println("調用方法hange2后arr的內存地址:"+System.identityHashCode(arr)); System.out.println("調用change2方法后:"+arr[1]); } private void change1(String s, Integer i){ String str = "1"; System.out.println("新定義str(與未改變的s相同):"+System.identityHashCode(str)); s = "2"; System.out.println("方法里改變s后內存地址:"+System.identityHashCode(s)); i = 2; } private void change2(String[] arr){ arr[1] = "lll"; System.out.println("方法hange2的arr的內存地址:"+System.identityHashCode(arr)); }
//結果
如圖:方法中形參的“s”(String類型)改變后地址發生了變化,只是形參的“s”(這里也可以隨便起個名稱如“s1”,“s2”)地址發生了改變,主方法實參“s”地址一直是原地址
故:在方法中形參地址改變不會影響到實參地址;
基本類型和String值改變是會改變對應的地址,但主方法“s”和“i”指向地址一直未變;故不會發生改變
**** 注意:因為Integer和String都是final修飾,改變值后會指向新的地址;
arr是引用類型在方法change2中修改后。方法中的形參“arr”和主方法中的實參“arr”指向的還是同一個地址,故改變后主方法實參“arr”指向地址的值發生改變,實參“arr”發生改變;
故:引用類型的形參的引用地址與實參一樣時,形參改變會影響到實參(非String和基本類型)
舉例:如果change2的方法中寫的是 arr = new String[]{};
也就是
private void change2(String[] arr){ //arr[1] = "lll"; arr = new String[]{"222", "333"}; System.out.println("方法hange2的arr的內存地址:"+System.identityHashCode(arr)); }
結果(在主方法中arr未改變):
在change2中arr = new String[]{"222", "333"};相當於給方法中的形參“arr”指向了一個新的地址(此時change2中的“arr”和主方法中的“arr”指向地址已經不同),此時形參“arr”改變已經影響不到實參“arr”;
因此又證明了:在方法中形參地址改變不會影響到實參地址;
舉例:如下面代碼:
public class TestPerson { public static void main(String[] args) { Person p1 = new Person("張無忌"); Person p2 = new Person("趙敏"); System.out.println("p1原值:"+p1); System.out.println("p2原值:"+p2); System.out.println("p1內存地址:"+System.identityHashCode(p1)); System.out.println("p2內存地址:"+System.identityHashCode(p2)); change3(p1, p2); System.out.println(); System.out.println("調用change3之后p1值:"+p1); System.out.println("調用change3之后p2值:"+p2); System.out.println("調用change3之后p1內存地址:"+System.identityHashCode(p1)); System.out.println("調用change3之后p2內存地址:"+System.identityHashCode(p2)); } public static void change3(Person x, Person y){ Person temp = x; x = y; y = temp; System.out.println(); System.out.println("change3方法中交換后(之前x=p1;現在x=p2)x="+x); System.out.println("change3方法中交換后(之前y=p2)y="+y); System.out.println("change3方法中交換后(之前x=p1;現在x=p2)x內存地址:"+System.identityHashCode(x)); System.out.println("change3方法中交換后(之前y=p2)y內存地址:"+System.identityHashCode(y)); } } class Person{ public String name; public Person(String name) { this.name = name; } @Override public String toString() { return "Person [name=" + name + "]"; } }
在change3中只不過是讓x和y的引用地址發生了改變;但不會影響到原有的p1和p2指向的地址
開始p1和x指向同一個地址,p2和y指向同一個地址,在方法未交換之前實參和形參的地址(即p1->17984913、x->17984913、p2->14116828、y->14116828),調用方法后因為x和y互換(即p1->17984913、x->14116828、p2->14116828、y->17984913)p1和p2不變,x和y地址互換,之后沒發生具體值的改變,且p1和y指向同一個地址,p2和x指向對一個地址,故p1和p2不會發生變化;
舉例:p1發生變化
public static void change3(Person x, Person y){ Person temp = x; x = y; y = temp; y.name="張三"; System.out.println(); System.out.println("change3方法中交換后(之前x=p1;現在x=p2)x="+x); System.out.println("change3方法中交換后(之前y=p2)y="+y); System.out.println("change3方法中交換后(之前x=p1;現在x=p2)x內存地址:"+System.identityHashCode(x)); System.out.println("change3方法中交換后(之前y=p2)y內存地址:"+System.identityHashCode(y)); }
//結果
在方法中交換之后p1個y指向同一個地址 如上圖y和p1內存地址為8600110;故地址相同,修改y.name = "張三"; (即地址8600110的內容改變),因為p1也是指向8600110所以p1也會發生變化;
故:當形參的引用地址與實參一樣時,形參改變會影響到實參(非String和基本類型)
.