轉自http://www.cnblogs.com/androidsuperman/p/9012320.html
首先對傳值和傳引用要有個基本的概念
傳值:傳遞的是值的副本。方法中對副本的修改,不會影響到調用方。
傳引用:傳遞的是引用的副本,共用一個內存,會影響到調用方。此時,形參和實參指向同一個內存地址。對引用副本本身(對象地址)的修改,如設置為null,重新指向其他對象,不會影響到調用方。
直接上代碼,更好的理解兩者的區別。首先看傳基本數據類型,如int、long等。
// 基本數據類型 public class ParamChangeValue { public static void main(String[] args) { int s = 1; System.out.println("args = [" + s + "]"); change(s); System.out.println("args = [" + s + "]"); } private static void change(int i){ i = i* 5; } }
輸出:
args = [1]
args = [1]
從輸出的的結果中可以看到原本的s並沒有被修改,即傳值傳遞的是值的副本,不會影響到本身。
再來看傳對象。
// 對象 public class ObjectChangeValue { public static class Score{ private int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; } } public static void main(String[] args) { Score score = new Score(); score.setValue(1); System.out.println("args = [" + score.getValue() + "]"); change(score); System.out.println("after args = [" + score.getValue() + "]"); } private static void change(Score score){ score.setValue(2); } }
輸出:
args = [1]
after args = [2]
從結果中我們可以看到score實例的value值被修改了,因為傳引用后指向的是同一個地址,修改的實際上也就是這個地址上的值,另外要注意一點的是如果對象被重新創建或賦值為null,即new會重新指向其他對象,不影響其原對象的值。
第三部分:傳String、Integer等immutable類型。
// String、Integer、Long等 public class StringChangeValue { public static void main(String[] args) { String s = "test1"; System.out.println("args = [" + s + "]"); change(s); System.out.println("args = [" + s + "]"); } private static void change(String i){ i = i + " test value"; } }
只要知道String、Integer類是final類型的就明白輸出的結果為什么是這樣的。
總結:基本類型(byte,short,int,long,double,float,char,boolean)為傳值;對象類型(Object,數組,容器)為傳引用;String、Integer、Double等immutable類型因為類的變量設為final屬性,無法被修改,只能重新賦值或生成對象。當Integer作為方法參數傳遞時,對其賦值會導致原有的引用被指向了方法內的棧地址,失去原有的的地址指向,所以對賦值后的Integer做任何操作都不會影響原有值。