1. 程式人生 > >Java 傳值和傳引用的區別

Java 傳值和傳引用的區別

首先對傳值和傳引用要有個基本的概念

  • 傳值:傳遞的是值的副本。方法中對副本的修改,不會影響到呼叫方。
  • 傳引用:傳遞的是引用的副本,共用一個記憶體,會影響到呼叫方。此時,形參和實參指向同一個記憶體地址。對引用副本本身(物件地址)的修改,如設定為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";    
    }
}

輸出:
args = [test1]
args = [test1]

只要知道String、Integer類是final型別的就明白輸出的結果為什麼是這樣的。

總結:基本型別(byte,short,int,long,double,float,char,boolean)為傳值;物件型別(Object,陣列,容器)為傳引用;String、Integer、Double等immutable型別因為類的變數設為final屬性,無法被修改,只能重新賦值或生成物件。當Integer作為方法引數傳遞時,對其賦值會導致原有的引用被指向了方法內的棧地址,失去原有的的地址指向,所以對賦值後的Integer做任何操作都不會影響原有值。