1. 程式人生 > >弄懂Java為何只有值傳遞

弄懂Java為何只有值傳遞

最近有同學問我關於Java中值傳遞與引用傳遞的問題,在此小結一下

值傳遞是指在函式呼叫時將實參內容複製一份傳遞給形參,這樣在函式中改變該引數不會對原引數產生影響。

引用傳遞是指將物件地址的引用傳遞給該函式,這樣在函式中改變該引數會對原引數產生影響。

兩者的主要區別在於:是否將實參內容複製一份傳遞給了形參!

舉個最簡單的例子:

public class test {
    public static void main(String[] args) {
        int num = 10;
        changeNum(num);
        System.out.println(num);
    }

    public static void changeNum(int num){
        System.out.println(num);
        num = 20;
        System.out.println(num);
    }
}

執行結果如下: 都知道這是值傳遞,將實參內容10複製一份傳遞給了該函式,對原引數不產生影響。

 

這個例子開始犯迷糊,以為是傳遞該地址過去 

public class test {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setName("張三");
        p1.setSex("男");
        changePerson(p1);
        System.out.println(p1);
    }

    public static void changePerson(Person person){
        person.setName("小花");
        person.setSex("女");
    }
}

public class Person {
    private String name;
    private String sex;

    //省略了getter/setter/toString        
}

執行結果如下:我同學在這裡犯的迷糊,跟我說是引用傳遞

 

將test類的程式碼稍加修改加兩行程式碼:

public class test {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setName("張三");
        p1.setSex("男");
        changePerson(p1);
        System.out.println(p1);
    }

    public static void changePerson(Person person){
        person = new Person();
        person.setName("小花");
        person.setSex("女");
        System.out.println(person);
    }
}

執行結果如下:可見並不是引用傳遞,如果是引用傳遞則兩次輸出結果都改為name=小花,sex=女了。

 

 

 還是前面所說:兩者的主要區別在於:是否將實參內容複製一份傳遞給了形參!

此處還是值傳遞,複製了實參內容,只不過實參內容是該物件的地址值,注意地址值也是值!

舉個例子:你把你家的鑰匙刻了一把給B,B拿著刻印的鑰匙去你家打掃衛生,等你回來時發現家裡變乾淨了,你家受到了影響,但你的鑰匙並沒有受到影響。

 

另一個容易對Java值/引用傳遞犯迷糊的例子:執行結果為:“abc”

public class test {
    public static void main(String[] args) {
     String s1 = "a"+"b"+"c";
     changeStr(s1);
     System.out.println(s1);
    }

    public static void changeStr(String str){
        str+="d";
    }
}

關於String類有一點特殊,它是不可變類,建議瞭解下我之前小結的搞定Java String面試題

關於字串中的"+"號:Java有這麼一串話:

java語言提供了字串串聯運算子特殊支援( + ),和其他物件轉換為字串。字串連線是通過StringBuilder實施(或StringBuffer)類及其append方法。字串的轉換是通過方法toString實施,由Object和繼承的所有類的java。

所以該str+="d"等於String str = new StringBuffer(str).append("d").toString();  

所以此處相當於新建了一個String物件。

&n