許多編程語言都有2種方法將參數傳遞給方法------按值傳遞和按引用傳遞。java
與其餘語言不一樣,Java不容許程序員選擇按值傳遞仍是按引用傳遞各個參數,基本類型(byte--short--int--long--float--double--boolean--char)的變量老是按值傳遞。就對象而言,不是將對象自己傳遞給方法,而是將對象的的引用或者說對象的首地址傳遞給方法,引用自己是按值傳遞的-----------也就是說,講引用的副本傳遞給方法(副本就是說明對象此時有兩個引用了),經過對象的引用,方法能夠直接操做該對象(當操做該對象時才能改變該對象,而操做引用時源對象是沒有改變的)。程序員
如今說說數組:若是將單個基本類型數組的元素傳遞給方法,並在方法中對其進行修改,則在被調用方法結束執行時,該元素中存儲的並非修改後的值,由於這種元素是按值傳遞,若是傳遞的是數組的引用,則對數組元素的後續修改能夠在原始數組中反映出來(由於數組自己就是個對象,int[] a = new int[2];,這裏面的int是數組元素的類型,而數組元素的修改是操做對象)。編程
對於單個非基本類型數組的元素在方法中修改,則在被調用方法結束執行時,該元素中存儲的是修改後的值,由於這種元素是按引用傳遞的,對象的改動將在源數組的數組元素中反映出來。小程序
下面看個小程序:api
public class Test{ String str = new String("good"); char[] ch = {'a','b','c'}; int i = 10; public void change(String str,char[] ch,int i){ str = "test ok"; ch[0] = 'g'; i++; } public static void main(String[] args){ Test tt = new Test(); tt.change(tt.str,tt.ch,tt.i); System.out.println(tt.i); System.out.print(tt.str+" and "); System.out.println(tt.ch); } }
str是String類型的引用,i是基本類型變量,ch是數組名,也是數組對象的引用數組
在chang()方法裏,str="test ok",是一個新的對象把首地址放在引用變量str上;bash
而ch[0]='g';由於傳的是數組的引用,而此時ch[0]='g';是對數組元素的操做,能修改源數組的內容;app
i是整型值,只是把值copy了一份給方法,在方法的變化是不改變的源i的。編程語言
因此結果是:this
10 good and gbc
如今我們把代碼變化一下:
public class Test{ String str = new String("good"); char[] ch = {'a','b','c'}; int i = 10; public void change(String str,char ch,int i){ str = "test ok"; ch = 'g'; this.i = i+1; } public static void main(String[] args){ Test tt = new Test(); tt.change(tt.str,tt.ch[0],tt.i); System.out.println(tt.i); System.out.print(tt.str+" and "); System.out.println(tt.ch); } }
仔細觀察下實參以及入參有何變化?
change()方法裏的入參char[] ch變成--------------char ch;
此次傳遞的是個char值的單個數組元素,按照上面的解析,此時ch='9';是不影響源數組元素的。
this.i = i+1;這裏面等號左邊的i是屬性i,等號右邊的i是局部變量(入參裏的i);
此時i+1後賦值給屬性的i,天然會改變屬性i的值,同時17行,tt.i又是調用屬性的i,此次的結果是:
11 good and abc
如今是否是有點明白了?
那好再看下面一個小程序
public class Test{ public void change(StringBuffer x,StringBuffer y){ x.append(y); y=x; } public static void main(String[] args){ StringBuffer buffA = new StringBuffer("a"); StringBuffer buffB = new StringBuffer("b"); new Test().change(buffA,buffB); System.out.println(buffA+","+buffB); } }
此次傳遞的是兩個對象的引用的值,
在方法change()裏 的x.append(y), 其中引用x調用api方法append()修改了new StringBuffer("a");的內容。
y=x;是一個修改內容的對象把首地址賦值給引用變量y了,此時操做的是引用,而先前y是new StringBuffer("b");的引用變量,因此輸出結果是:
ab,b
下面是個稍難的小程序,先本身用筆畫畫過程,寫出本身的結果,然後再上機操做下,若是本身的結果和在電腦上的結果同樣,那麼再碰到這類題就不難了,若是不同,回頭仔細體會下我前面的講解,找找緣由。
public class Test{ private String nn = new String("1"); private String[] mm = {"2","5"}; void test(String nn,String[] mm){ nn = new String("3"); this.nn = "9"; mm[0] = "4"; System.out.println("in test(),mm[0]: "+mm[0]); mm = new String[]{"8","7"}; System.out.println("in test(),nn: "+nn); System.out.println("this.nn: "+this.nn); System.out.println("mm[0]: "+mm[0]); } public static void main(String[] args){ Test s = new Test(); s.test(s.nn,s.mm); System.out.println(s.nn+" "+s.mm[0]); } }