2017年6月15日 星期四

Call/Pass by Reference

※Call/Pass by Reference 

Call/Pass by Value:將變數傳進另一隻方法當參數,方法對這個變數所做的事,和原本的沒有關係。 基本型態

Call/Pass by Reference:將變傳進另一隻方法當參數,方法對這個變數所做的事,會影響到原來的。不是基本型態的屬於這個



public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    System.out.println(list);
    xxx(list);
    System.out.println(list);
}
    
public static void xxx(List<String> a){
    a.add("a1");
}

※結果:
[]
[a1]



※new

public static void xxx(List<String> a){
    a.add("a1");
    a.add("a2");
    
    // a = null;
    a = new ArrayList<String>();
    a.add("a3");
    a.add("a4");
    System.out.println("in" + a);
}

※結果:
[]
in[a3, a4]
[a1, a2]

※受影響的只在 new 之前,之後自己是獨立的

※a = null、a = 另外一個 List也都和 new 一樣,對原來的 List 不會產生作用,因為指向了別的記憶體空間

在 C++ 語言裡,java 只有 call by value,只不過傳的是地址而已,所以不能將整個物件改掉,如這個例子,new 或者將別的記憶體空間指定過來就和原來的沒關係了,但如果物件裡的方法可以改變內容是可以的,如上個例子的 List 的 add 方法就是這樣

這篇文章有說明,C++ 用 &變數名稱就表示 call by reference,從右邊賦值到左邊是可以的



※另一個範例
public class Test {
    private String xxx = "x";
    // setter/getter...
    
    private List<String> list = new ArrayList<>();
    // setter/getter...

    
    Test() {
        list.add("a");
        list.add("b");
        list.add("c");
    }
        
    public static void main(String[] args) {
        Test t1 = new Test();
        Test2 t2 = new Test2();
    
        t2.setXxx2(t1.xxx);//*
        t2.ooo(t1.getXxx());
        System.out.println(t1.getXxx());
        System.out.println(t2.getXxx2());
    
        System.out.println("\r\n");
    
        t2.setList2(t1.getList());//*
        t2.xxx(t1.getList());
        System.out.println(t1.getList());
        System.out.println(t2.getList2());
    }
}
    
class Test2 {
    private String xxx2;
    // setter/getter...

    private List<String> list2;
    // setter/getter...
    
    public void xxx(List<String> l) {
        l.add("d");
        l.add("e");
        l.add("f");
    }
    
    public void ooo(String s) {
        s = "o";
    }
}



沒有留言:

張貼留言