一段代碼引發的思考——java值傳遞和引用傳遞

今天小夥伴問我一段代碼:

  public static ListNode create(int[] array) {
        if (array == null || array.length == 0)
            return null;
        ListNode head = new ListNode(0);
        ListNode node = head;
        for (int i = 0; i < array.length; i++) {
            ListNode temp = new ListNode(array[i]);
            node.next = temp;
            node = temp;
            System.out.println(node.val);
        }
        return head.next;
    }

爲什麼在方法內head指向的是鏈表的最後一個結點,但是在main方法中head指向的是第一個結點。

我進行了測試



public class Main {

    public static class ListNode{
        int val;
        ListNode next; //下一個鏈表對象
        ListNode(int x){val=x;}  //賦給結點的值
    }

    public static ListNode create(int[] array) {
        if (array == null || array.length == 0)
            return null;
        ListNode head = new ListNode(0);  //預指針,其下一個結點指向真正的頭結點
        ListNode node = head;
        for (int i = 0; i < array.length; i++) {
            ListNode temp = new ListNode(array[i]);
            node.next = temp;
            node = temp;
            System.out.println(node.val);
        }
        return head.next;
    }

    public static void main(String[] args)
    {
        int[] array={1,2,3,4,5,6,7,8,9};
        ListNode a=create(array);
        System.out.println("---------"+a.val);
    }
}

發現真的是a.val輸出爲1。

後來經過一波討論,查閱了很多資料得出一下結論。

這是因爲ListNode a=create(array);被初始化,將head.next的初值1賦值給了a。然後再執行create方法。但由於java的引用傳遞,雖然方法內head的最後的值變爲9,但是最後賦值給a的值依然爲其初始值1。

值傳遞:
在方法被調用時,實參通過形參把它的內容副本傳入方法內部,此時形參接收到的內容是實參值的一個拷貝,因此在方法內對形參的任何操作,都僅僅是對這個副本的操作,不影響原始值的內容。

引用傳遞:
引用也就是指向真實內容的地址值,在方法調用時,實參的地址通過方法調用被傳遞給相應的形參,在方法體內,形參和實參指向內存地址,對形參的操作會影響的真實值。

JVM內存模型中,方法是存在虛擬棧中的,一個線程獨享一個棧,而堆和方法區是所有線程共享的。JAVA的引用傳進函數時 , 會複製一個引用與實參指向同一對象的引用, 操作的不是同一個引用。如下圖所示:

總的來說就是隻有當變量本身的值發生改變,值纔會改變。

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