String、StringBuilder函數傳參的執行過程

遇到下面一段代碼,結果是什麼:

public class StringbuilderAppend {
    public static  void test(StringBuilder x,StringBuilder y){
        x.append(y);
        y=x;
    }
    public static void main(String[] args) {

        StringBuilder a=new StringBuilder("A");
        StringBuilder b=new StringBuilder("B");
        test(a,b);
        System.out.println(a);
        System.out.println(b);
    }
}

在這裏插入圖片描述
發現和我想的不一樣,不是說java參數傳遞是值傳遞(傳的是棧空間的值,對於引用對象傳的就是地址了)嗎?爲什麼執行完程序,結果卻和自己想的不一樣呢?
原來還是對String、StringBuilder類型理解的不夠透徹;下面就來分析一下:

StringBuilder的append方法,append方法的操作是直接在原來的數據上進行字符串拼接;append操作是在原有對象的基礎上進行的;

執行過程如下:

代碼中a、b爲實參,調用函數,將a的地址 、b的地址傳遞給形參x、y,會發現a、x地址相同,指向同一個值;b、y地址相同,指向同一個值;如圖:

在這裏插入圖片描述
在函數中,執行

        x.append(y);
        y=x;

由於append方法是在原有對象的數據上進行操作的,所以執行完x.append(y);這一句代碼後,x指向的數據就變化了,但x的地址沒有變,又由於a和x的地址一樣,指向同一個對象,雖然a和x的指向都沒變,但是他們指向的數據發生了改變;所以a地址指向的數據也變化了;

y=x;這使形參y指向x的對象,只改變了形參y的指向,並沒有改變實參b的指向,所以b的值不變;如圖:

在這裏插入圖片描述

再來說一下String,先通過一段代碼來引入:

public class StringTest {

    public  static void test(String x,String y){

        x=x+"A";
        y=y+"A";
        System.out.println("x:"+x);
        System.out.println("y:"+y);
    }
    public static void main(String[] args) {
        String a="C";
        String c="D";
        test(a,c);
        System.out.println(a);
        System.out.println(c);
    }
}

結果爲:
在這裏插入圖片描述
首先,我們要明確一點:String類型是不可變的,是指其地址不可變,但其引用指向的內容是可變的;
String類由final修飾:
public final class String implements Serializable, Comparable<String>, CharSequence
且String類繼承了Comparable接口,自身帶有比較的功能;

上述代碼的執行如下:
代碼中a、c爲實參,調用函數,將a的地址 、c的地址傳遞給形參x、y,會發現a、x地址相同,指向同一個值;c、y地址相同,指向同一個值;
在這裏插入圖片描述
在函數中,對x、y進行操作,

        x=x+"A";
        y=y+"A";

因爲String類型是不可變的(引用不可變,引用指向的內容可變),它是取出x的值與‘A’相拼接,形成一個新的String對象使 x重新 指向該新對象;所以 x 的地址改變了,指向的值改變了,但a的地址並沒有變,且a指向的內容也沒有變;同理,對y和c也是一樣,所以會出現這樣的結果;
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章