2014年12月3日水曜日

参照型の引数は参照渡しではない

Javaのメソッドの引数は、参照型の場合は参照渡しになると思っていませんか?

そもそも、値渡しとはメソッドを呼ぶときに、引数にはその値のコピーを渡すもので、メソッド内でそのコピーされた値を書き換えても、元の引数は変更されないという動きになります。

一方、参照渡しとはメソッドの引数を呼ぶときに、引数にはその値の参照を渡すもので、メソッド内でその参照先を書き換えると、元の引数も書き換わってしまうという動きになります。

確かに、下のようなコードだと参照渡しのような動きをします。


class Ref1 {
  public static void main(String[] args) {
    // サンプル1
    int[] array = {10, 20, 30};
    System.out.println("呼び出し前:" + array[0]);
    method(array);
    System.out.println("呼び出し後:" + array[0]);
  }

  static void method(int[] array){
    //引数の配列のindex0を書き換える
    array[0] = 100;
  }
}


実行結果

呼び出し前:10
呼び出し後:100



しかし、以下のようなコードだとどうなるでしょう?

class Ref2 {
  public static void main(String[] args) {
    // サンプル2
    int[] array = {10, 20, 30};
    System.out.println("呼び出し前:" + array[0]);
    method(array);
    System.out.println("呼び出し後:" + array[0]);
  }

  static void method(int[] array){
    int[] nums = {100, 200, 300};
    //引数で渡された配列を書き換える
    array = nums;
  }
}


実行結果

呼び出し前:10
呼び出し後:10


メソッドの引数で渡された配列を書き換えているのに、メソッド実行後も配列の中身は変わっていません。

これはメソッドの引数が参照型の場合は、アドレス値をコピーしたものが引数として渡されているからです。
つまりは、基本型も参照型も値渡しをしているということです。

引数として渡されたアドレスの参照先である実体を操作することは可能です。
しかし、アドレス値そのものを書き換えても、コピーしたものを上書きしただけなので、元のアドレス値は何も変わらないというわけです。

0 件のコメント:

コメントを投稿