1. 程式人生 > >Java函數的傳參機制

Java函數的傳參機制

輸出結果 如果 傳遞 出錯 結束 arraylist 多人 判斷 方法

最近的一個項目,裏面各種返回void,參數用引用類型,那叫一個熟和多,但是也把我繞糊塗了。

我就打算好好理一理java的傳參機制,整理一番

很多人一聽Java的傳參,那一定會脫口而出,java都是值傳遞的。恭喜各位,答對了。

那麽,傳的是什麽值?

如果參數類型是原始類型,那麽傳過來的就是這個參數的一個副本,也就是這個原始參數的值,這個跟之前所談的傳值是一樣的。如果在函數中改變了副本的值不會改變原始的值.

如果參數類型是引用類型,那麽傳過來的就是這個引用參數的副本,這個副本存放的是參數的地址。如果在函數中沒有改變這個副本的地址,而是改變了地址中的 值,那麽在函數內的改變會影響到傳入的參數
如果在函數中改變了副本的地址,如new一個,那麽副本就指向了一個新的地址,此時傳入的參數還是指向原來的 地址,所以不會改變參數的值。

這裏我給個代碼就很好理解了
 1 public class ParamterTest {
 2     public static void main(String[] args) {
 3         List<Integer> list1 = new ArrayList<>();
 4         List<Integer> list2 = new ArrayList<>();
 5         list1.add(0);
6 list2.add(0); //(1) 7 f(list1, list2); 8 System.out.println("list1 2"); 9 p(list1); 10 System.out.println("list2 2"); 11 p(list2); //(4) 12 } 13 14 public static void f(List<Integer> list1, List<Integer> list2) {
15 list1.add(1); 16 list2.add(1); 17 list2 = new ArrayList<>(); //(2) 18 list1.add(2); 19 list2.add(2); 20 System.out.println("list1 1"); 21 p(list1); 22 System.out.println("list2 1"); 23 p(list2); //(3) 24 } 25 26 public static void p(List<Integer> list) { 27 for (Integer i : list) { 28 System.out.println(i); 29 } 30 } 31 }

輸出結果

list1 1
0
1
2
list2 1
2
list1 2
0
1
2
list2 2
0
1

要具體解釋,就是涉及到堆,棧和方法區了。

(1)list1,list2剛剛成立,都放進了 0,因為是對象的實例所以保存在堆裏面

(2)list1,list2將自己堆的地址傳到了方法裏,因為是引用所以保存在棧裏面,並通過地址往堆裏面的實例,放進了 1。但是,此時new了一個實例,list2在棧裏面不再指向堆的實例,而是一個新的地址。

(3)list1,list2放進了2,但此處list1依然指向堆的實例,故放進了 2,而list2則是新的地址堆的list2並沒有放進 2

(4)方法結束,返回的結果使堆的list1,放進了 1 , 2 。list2 因為在方法內中途有新的實例, 只放進了 1 ,而沒有 2。

其實一直迷惑我們,是我們判斷出錯的是String ,明明是一個引用類型,卻是基本類型的特性,因為String 實際上是[]char,具體不細說,我就丟個代碼,讓大家跑跑吧。

public class ParamterStringTest {
    public static void main(String[] args) {
        String s1 = "a";
        String s2 = "a";
        f(s1, s2);
        System.out.println("s1 2");
        p(s1);
        System.out.println("s2 2");
        p(s2);
    }

    public static void f(String s1, String s2) {
        s1 = "b";
        s2 = "b";
        System.out.println("s1 1");
        p(s1);
        System.out.println("s2 1");
        p(s2);
    }

    public static void p(String s) {
        System.out.println(s);
    }

}

同理,相應的Interge等包裝類。

Java函數的傳參機制