1. 程式人生 > >Java中方法引數的傳遞機制

Java中方法引數的傳遞機制

值傳遞是對基本型變數而言的,傳遞的是該變數的一個副本,改變副本不影響原變數.

引用傳遞一般是對於物件型變數而言的,傳遞的是該物件地址的一個副本, 並不是原物件本身 。

一般認為,java內的基礎型別資料傳遞都是值傳遞. java中例項物件的傳遞是引用傳遞

  • 值傳遞的時候,將實參的,copy一份給形參。
  • 引用傳遞的時候,將實參的地址值,copy一份給形參。

注意:

    String和包裝型別是不可變的,所以當方法引數型別為String或包裝型別的時候,也是值傳遞,即原先的值不會改變

例如:

public class Test {
    public static void main(String[] args) {
        int i = 1;
        String str = "hello";
        Integer num = 200;
        int[] arr = {1,2,3,4,5};
        MyData my = new MyData();
        
        change(i,str,num,arr,my);
        
        System.out.println("i = " + i); //1
        System.out.println("str = " + str);//hello
        System.out.println("num = " + num);//200
        System.out.println("arr = " + Arrays.toString(arr));//{2,2,3,4,5}
        System.out.println("my.a = " + my.a);//11
    }
    public static void change(int j, String s, Integer n, int[] a,MyData m){
        j += 1;
        s += "world";
        n += 1;
        a[0] += 1;
        m.a += 1;
    }
}
class MyData{
    int a = 10;
}

為什麼會出現上面的結果呢?

第一個引數: 

                當我們傳入  int i的時候,由於int 為基本資料型別,所以會 ‘值傳遞’,copy一份變數,

                然後在進行  j += 1操作,相當於  j = i + 1 = 1 + 1 =2,但是對i本身並沒有改變

第二個引數:

               當我們傳入String型別的形參時,由於String時一個物件,所以會進行 ‘引用傳遞’

               但是由於String類為一個final類,所以str是不可變的,那麼 s += 'world'會建立一個新的String物件

                既然建立了一個新的物件,那麼和原先的String物件就沒有必然聯絡,所以str依然為 ‘hello’

第三個引數:

               第三個引數為Integer型別,由於Integer 時一個物件,那麼會進行  ‘引用傳遞’,但是由於Integer也是一個 final類,

                所以和第二個引數的情況一樣,會產生一個新的物件,和原先的物件沒有必然聯絡,所以  num依然為200

第4個引數:

             由於陣列將引用存放到棧中,將資料放在堆中,所以  會進行‘引用傳遞’,

             所以會將arr在棧中的引用地址傳給a,所以現在arr與a指向相同的堆地址,那麼當a進行資料修改後,

             堆中的資料會進行改變,由於arr和a指向相同堆地址,所以  arr列印的時候也會改變

第5個引數:

              MyData是一個物件,會進行‘引用傳遞’,和引數4的情況一樣,所以會列印11