方法傳值Call by value

在Java中,只有Call by value,然後要忘記c++的知識,java沒有像c++有call by address, call by reference。

Java的reference,與C++的reference是完全不同的理念。

方法就是函式,也就是物件中所定義的函式,物件定義的函式就叫作成員方法,也叫作成員函式,二者是一樣的意思。

什麼是call by value?

參數一進入方法,方法即建立新的變數保管這些參數值,同時新變數的資料型態完全吻合參數的資料型態,這種傳遞參數的方式會先把參數複製一份,稱為傳值呼叫(call by value)。

修改成員變數

以下的程式碼要傳遞testClz變數給函式changeClz(),實際上是複製testClz記憶體位址給arg1的「區域」變數(參考下圖)。

img

找到age的記憶體位址,並修改裡面的值為100。

1
arg1.age = 100;

對於物件記憶體位址有興趣,可以參考c++物件記憶體布局:

1
  arg1.age = 100;    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Teest {
  public static void main(String[] args) {
    Teest test = new Teest();
    TestClz testClz = new TestClz();
    testClz.age = 50;
    test.changeClz(testClz);
    System.out.println(testClz.age);
  }
  public void changeClz(TestClz arg1) {
    arg1.age = 100;
  }
}
class TestClz {
  public int age;
}
100

修改參數的記憶體位址

以下的程式碼要傳遞testClz變數給函式changeClzRef(),實際上是複製testClz記憶體位址給arg1的「區域」變數。

接著arg1區域變數原本指向0x12345678,改成指向0x12345689

1
  arg1 = new TestClz();

img

此時此刻,arg1區域變數與testClz變數指的都不是相同物件,所以執行結果是50,而不是印出60,區域變數arg1離開changeClzRef()方法,就立即被記憶體釋放。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Teest {
  public static void main(String[] args) {
    Teest test = new Teest();
    TestClz testClz = new TestClz();
    testClz.age = 50;
    test.changeClzRef(testClz);
    System.out.println(testClz.age);
  }
  public void changeClzRef(TestClz arg1) {
    arg1 = new TestClz();
    arg1.age = 60;
  }
}
class TestClz {
  public int age;
}
50

此處的概念跟C++的call by addresscall by reference完全不同,是不一樣的概念,請勿混為一談。

results matching ""

    No results matching ""