弄懂Java為何只有值傳遞
最近有同學問我關於Java中值傳遞與引用傳遞的問題,在此小結一下
值傳遞是指在函式呼叫時將實參內容複製一份傳遞給形參,這樣在函式中改變該引數不會對原引數產生影響。
引用傳遞是指將物件地址的引用傳遞給該函式,這樣在函式中改變該引數會對原引數產生影響。
兩者的主要區別在於:是否將實參內容複製一份傳遞給了形參!
舉個最簡單的例子:
public class test { public static void main(String[] args) { int num = 10; changeNum(num); System.out.println(num); } public static void changeNum(int num){ System.out.println(num); num = 20; System.out.println(num); } }
執行結果如下: 都知道這是值傳遞,將實參內容10複製一份傳遞給了該函式,對原引數不產生影響。
這個例子開始犯迷糊,以為是傳遞該地址過去
public class test { public static void main(String[] args) { Person p1 = new Person(); p1.setName("張三"); p1.setSex("男"); changePerson(p1); System.out.println(p1); } public static void changePerson(Person person){ person.setName("小花"); person.setSex("女"); } } public class Person { private String name; private String sex; //省略了getter/setter/toString }
執行結果如下:我同學在這裡犯的迷糊,跟我說是引用傳遞
將test類的程式碼稍加修改加兩行程式碼:
public class test { public static void main(String[] args) { Person p1 = new Person(); p1.setName("張三"); p1.setSex("男"); changePerson(p1); System.out.println(p1); } public static void changePerson(Person person){ person = new Person(); person.setName("小花"); person.setSex("女"); System.out.println(person); } }
執行結果如下:可見並不是引用傳遞,如果是引用傳遞則兩次輸出結果都改為name=小花,sex=女了。
還是前面所說:兩者的主要區別在於:是否將實參內容複製一份傳遞給了形參!
此處還是值傳遞,複製了實參內容,只不過實參內容是該物件的地址值,注意地址值也是值!
舉個例子:你把你家的鑰匙刻了一把給B,B拿著刻印的鑰匙去你家打掃衛生,等你回來時發現家裡變乾淨了,你家受到了影響,但你的鑰匙並沒有受到影響。
另一個容易對Java值/引用傳遞犯迷糊的例子:執行結果為:“abc”
public class test { public static void main(String[] args) { String s1 = "a"+"b"+"c"; changeStr(s1); System.out.println(s1); } public static void changeStr(String str){ str+="d"; } }
關於String類有一點特殊,它是不可變類,建議瞭解下我之前小結的搞定Java String面試題
關於字串中的"+"號:Java有這麼一串話:
java語言提供了字串串聯運算子特殊支援( + ),和其他物件轉換為字串。字串連線是通過
StringBuilder
實施(或StringBuffer
)類及其append
方法。字串的轉換是通過方法toString
實施,由Object
和繼承的所有類的java。
所以該str+="d"等於String str = new StringBuffer(str).append("d").toString();
所以此處相當於新建了一個String物件。
&n