在java應用程序中,當對象的引用是傳遞方法一個參數時,傳遞的時該引用的一個副本,(按值傳遞)。而 非引用本身,調用方法的對象引用和副本都是指向同一個對象。 對象是按引用傳遞的,java應用程序中有且僅有一種參數傳遞機制---值傳遞 按值傳遞的語義就是當將一個參數傳遞給一個函數時,函數接受的是原始值的一個副本。 按引用傳遞的語義就是當將一個參數傳遞給一個函數時,函數接受的是原始值的內存地址,而非一個副本。 public class Test { public static void main(String args[]){ StringBuffer sb1 = new StringBuffer("good"); StringBuffer sb2 = sb1; sb2.append(" afternoon"); System.out.PRintln("sb1 == "+sb1); } } 運行的結果:good afternoon 對象的賦值操作是傳遞對象的引用,sb1和sb2都指的是同一個對象,這里的其實也是傳值,傳的是指針的值。這里的 賦值是指針之間的賦值。 1. 引用是一種數據類型,保存了對象在內存中的地址,這種類型即不是我們平時所說的簡單數據類型也不是類實例(對象); 2. 不同的引用可能指向同一個對象,換句話說,一個對象可以有多個引用,即該類類型的變量。
public class Test1 { public void fun(String s){ s = "hehe"; } public static void main(String args[]){ Test1 test = new Test1(); String str = "haha"; test.fun(str); System.out.println("str == "+str); } }
public class Test2 { public void fun(ArrayList al){ al.add("hehe"); al.add("haha"); } public static void main(String args[]){ Test2 test = new Test2(); ArrayList al = new ArrayList(); test.fun(al); Iterator it = al.iterator(); while(it.hasNext()){ System.out.println(""+(String)it.next()); } } }
public class Test3{ public void fun(ArrayList al){ ArrayList alA = new ArrayList(); alA.add("haha"); alA.add("hehe"); al = alA; } public static void main (String args[]){ Test3 test = new Test3(); ArrayList al = new ArrayList(); test.fun(al); System.out.println(""+al.size()); } }
通過以上例子可以得出 1、假如參數是不可變對象,如原語類型(i.e.int)或者不可變的對象類型(i.e.BigInteger) 這樣的參數是安全的,方法體內的任何動作都不會影響方法外的內容 2、對于可變對象的類型,如ArrayList v 對v調用add()、remove()等方法會導致方法外的變量的變化 這時可能會導致代碼的不安全 但是假如在方法體內對該參數有重新賦值的操作,如v = new ArrayList() 這樣v指向的地址已經變化,之后對v的任何操作也不會影響方法外的內容