Java是值傳遞的,對基本型變量而言的,傳遞的是該變量的一個副本,改變副本不影響原變量。對於對象型變量而言的,傳遞的是該對象地址的一個副本,,並非原對象自己 ,這裏也有人說是引用傳遞。因爲副本的地址和原對象地址一致,所以對副本的值進行操做時,會同步改變原對象值。html
可是一旦副本的地址被改變,副本的值的操做則不會影響原對象地址。(重點)java
public class Test { public static void main(String[] args) { int num = 0 ; changeNum(num); System.out.println("num="+num); } private static void changeNum(int num) { num = 1; } }
最終輸出結果是:num=0面試
由於這裏 changeNum(num);語句中的num傳遞的是num的副本,也就是形參,因此當副本變爲1,對實參原對象不影響,原對象仍是num=0;數組
public class Test { public static void main(String[] args) { Product p = new Product(); p.setProName("before"); p.setNum(0); changeProduct(p); System.out.println("p.proName="+p.getProName()); System.out.println("p.num="+p.getNum()); } private static void changeProduct(Product p) { p.setProName("after"); p.setNum(1); } } class Product { private int num; private String proName; public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getProName() { return proName; } public void setProName(String proName) { this.proName = proName; } }
最終輸出結果是:p.proName=after
和p.num=1
。函數
這裏咱們能夠看到 changeProduct(p); 該語句傳遞的是p內存中存儲的地址的副本,該地址就是new Product();的地址。在changeProduct方法中對p地址的副本指向的值進行操做,因爲副本地址和原地址同樣,因此至關於最終p地址指向的值也會發生變化。因此這裏的changeProduct方法能改變實參。this
可是存在如下特殊狀況,就是前言說的一旦副本的地址被改變。咱們再 changeProduct() 方法中添加一條語句;spa
private static void changeProduct(Product p) { p = new Product();//添加這條語句,至關於P的地址變成new Product()新對象的地址,不是主函數中的對象的地址 p.setProName("after"); p.setNum(1); }
這裏添加的這條語句 改變了副本的地址,致使副本指向新對象的地址,所以變成對新對象的操做,不影響主函數中的原對象,最終輸出結果是:p.proName=before
和p.num=0
。.net
首先要清楚一點,這種說法不正確:String str = "java",這就至關於String str = new String("java"),這是建立一個新的String的過程,不僅僅是賦值的過程。code
public class Test { public static void main(String[] args) { String str = "ab"; changeString(str); System.out.println("str="+str); } private static void changeString(String str) { str = "cd"; } }
猜猜這裏最終結果是什麼?htm
最終輸出結果是:str=ab 。(沒猜對的說明上面第二點還沒理解清楚)
解析:
str1 = "cd"
str2 = new String("cd");
System.out.println(str1 == str2); // false
說明str = "cd";不能被解釋爲以下:str = new String("cd");
這裏之因此最終顯示結果是「ad」,是由於main中的str的地址是常量池「ad」的地址,而在str = "cd"說明此時str的地址變成常量池「cd」的地址,地址改變,對實參原來的str無影響,因此最終輸出的仍是「ad」.
public class Example { String str = new String("good"); char[] ch = { 'a', 'b', 'c' }; public static void main(String args[]) { Example ex = new Example(); ex.change(ex.str, ex.ch); System.out.print(ex.str + " and "); System.out.print(ex.ch); } public void change(String str, char ch[]) { str = "test ok"; ch[0] = 'g'; } }
從以下4個選項選出最終輸出結果
A 、 good and abc B 、 good and gbc C 、 test ok and abc D 、 test ok and gbc
正確答案: B
解析:
ex.str如第3點所說的,其傳遞的地址副本在change方法中被改變,所以不影響原地址的對象,因此ex.str不變;
ch數組是對象,數組的父類也是Object。傳遞的是數組地址的副本,所以在change中副本地址沒改變,至關於對原對象進行操做,因此ch數組的值發送變化。