Java中方法參數傳遞是值傳遞還是引用傳遞?

通過一段代碼來引入今天的主題:猜一下下面這段代碼的執行結果是什麼?

public class Test {
    public static void swap1(int a,int b){
        int temp=a;
        a=b;
        b=temp;
        System.out.println("函數中:a:"+a+"  b:"+b);
    }
    public static void main(String[] args) {
        int a=10;
        int b=20;
        swap1(a,b);
        System.out.println("主方法:a:"+a+"  b:"+b);
    }
}

結果爲:
在這裏插入圖片描述
發現兩個變量經過一個函數調用交換之後,他們的值並沒有發生改變,通過這段代碼,我們認爲只是把這兩個變量(實參)拷貝了一份傳遞到函數中的形參中,並沒有改變這兩個變量原本的值;這種方式是值傳遞;

但是觀察下面這段代碼,會發現:

public class ParamTest {
   public static void swap2(int[] array){
        int temp=array[0];
        array[0]=array[1];
        array[1]=temp;
        System.out.print("函數中:");
        for(int i=0;i<array.length;i++){
            System.out.print(array[i]+" ");
        }
      System.out.println();
    }
   public static void main(String[] args) {
        int[] array=new int[]{1,2};
        swap2(array);
         System.out.print("主方法中:");
        for(int i=0;i<array.length;i++){
            System.out.print(array[i]+" ");
        }
    }
}

結果爲:
在這裏插入圖片描述
經過函數調用後,原始值竟然發生了改變,如果Java傳參是值傳遞的話,那經過函數調用之後,他們的值不是應該沒發生改變嗎?這是爲什麼呢?Java傳參不是值傳遞嗎?爲什麼會產生和上面不一樣的結果呢?

首先,我們要搞清楚值傳遞和引用傳遞的根本含義:
值傳遞:是指在調用函數時,把實際參數的拷貝一份傳遞給形式參數;在函數調用時,是對形參進行一系類操作,改變的是形參的值,實參的值並不會發生改變;
引用傳遞:是指在調用函數時,將實際參數的地址傳遞給形式參數;在函數調用中,如果該地址的指向發生了變化,則實參的引用指向的值也會發生變化;

Java中數據的存儲:
基本數據類型(八大基本數據類型)是存儲在內存中;
引用數據類型(如數組、對象)是存儲在內存中,而引用的對象的屬性值是存儲在內存中;使用new關鍵字創建出來的類型都是引用數據類型;

基本數據類型:

比如:int a=10;將a的值直接存儲在中;
在這裏插入圖片描述
引用對象類型:
int[] array=new int[]{1,2};將array數組的地址存放在中,然後根據該地址去中查找該數組的值;
在這裏插入圖片描述

而Java中函數傳參,確實是值傳遞,這個值傳遞,傳遞的是棧內存中的值;

對於基本數據類型,函數調用時:
將棧中的值(實參的值)複製了一份,賦值給形參,在函數中做的一系列變化,都是針對形參,並不影響實參的值;

在這裏插入圖片描述

對於引用數據類型,函數調用時:
也是將棧中的值(即地址,因爲引用類型的地址是存放在棧中的)複製了一份,賦值給形參,所以形參和實參的地址是一樣的,他們指向的是堆中的同一段內存,所以當在函數中,對形參進行一系列操作(比如重新賦值)時,如果形參指向的內存的內容發生了變化,則實參指向的內容也會發生變化(因爲形參和實參的地址一樣,它們指向堆中同一段內存);
在這裏插入圖片描述

所以,Java中函數調用時是值傳遞,只是傳遞的值是棧中的值,對於基本數據類型,棧中存儲的值就是變量額值;而對於引用數據類型,棧中存儲的值是該引用變量的地址;

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