今天作項目,發現了一個問題,當String做爲參數傳遞的時候,在函數內部改變值對外部的變量值無影響,以下代碼:java
public static void main(String[] args) { String str = "11111"; changeStr(str); System.out.println(str);//輸出11111 } public static void changeStr(String str){ str = "22222"; }
一開始很不解,後來想明白了,遂去對java參數傳遞作一個總結,以加深本身的基礎知識.函數
對於:測試
四類八種基本類型來講,傳遞的都是值,由於這些值是直接保存在棧內存中的,因此傳遞的時候直接拷貝過去了.spa
public static void main(String[] args) { int num = 0; change(num); System.out.println(num);//輸出0 } public static void change(int numChange){ numChange =5; }
結構以下圖,也所以最外層的num的值並無受到影響.code
對象傳遞,本質上也都是值傳遞,只不過傳遞的值是該引用的拷貝.看下面實例和圖解:對象
public static void main(String[] args) { Person person = new Person("aaa", 11); change(person); System.out.println(person);//輸出 bbb 11 } public static void change(Person personChange){ personChange.setName("bbb"); }
結構圖以下:
當執行change的時候,會把person變量的指向的地址拷貝一份給personChange,二者都指向同一個堆內存,即便後面作了set方法修改,可是對二者的執行毫無影響.blog
例二和以前的不一樣之處在change裏面,對personChange進行了new操做.代碼以下:內存
public static void main(String[] args) { Person person = new Person("aaa", 11); change(person); System.out.println(person);//輸出 aaa 11 } public static void change(Person personChange){ personChange = new Person("bbb",12); }
結構圖以下:博客
當執行change的時候,會把person變量的指向的地址拷貝一份給personChange,二者都指向同一個堆內存,接下new操做會在堆中從新建立一個person對象,此時personChange則指向這個對象,而原person的指向沒發生變化,故輸出aaa 11.class
例三是綜合例一和例二,前面兩個搞懂的話這個就很容易懂了.
public static void main(String[] args) { Person person = new Person("aaa", 11); change(person); System.out.println(person);//輸出 ccc 11 } public static void change(Person personChange){ personChange.setName("ccc"); personChange = new Person("bbb",12); }
結構圖以下:
讀者本身理解下,不懂的話再看看前面的,看看爲何輸出CCC 11
終於到最初的問題,爲何String是對象,可是卻不符合上面對象傳遞測試出來的結果?
public static void main(String[] args) { String str = "11111"; changeStr(str); System.out.println(str);//輸出11111 } public static void changeStr(String str){ str = "22222"; }
緣由:
由於String對象具備不可變性,因此針對操做str = "22222",在String池中不存在的時候,就是至關於str = new String(),這樣變化下的話,那麼就和例一 如出一轍了,具體圖就不畫了,但願對你有幫助.
ps:若是想改變的話,可使用Holder包裝類包裝String,能夠參考博文:Java基礎系列18:Holder技術的實現原理分析 | zifangsky的我的博客
要理解上面的結果,就要認爲Java中只有值傳遞: