LoginSignup
9
4

More than 5 years have passed since last update.

Javaの値渡しと参照渡し

Last updated at Posted at 2018-01-23

基本型

Javaのメソッドの引数に与えられる値は基本的に値渡しです。
値渡しというのは、引数に与えられた値がコピーされるということです。
なので、メソッド内で引数に対して変更が加えられても、それは引数のコピーに対して変更を加えていることになります。

そのため、以下のような動きになることは理解できると思います。

値渡しを一番理解しやすいプログラム
int count = 8;
plus(count);
Log.d(count);

void plus(int value) {
    int result = value * 2;
    Log.d(result);
}
結果
after applying plus 16
outside of method plus 8

参照型

参照型を引数に渡すと、参照値がコピーされます。

以下のコードで言えば、左辺が参照値で右辺が実際の値です。
左辺の参照値というのは例えていうと、右辺の実際の値が格納されているメモリの番地のことです。

List<String> list = new ArrayList<>();

東京都千代田区千代田1−1には皇居があります。
東京都千代田区千代田1−1が参照値で、皇居が実際の値みたいな関係です。

上記を踏まえて、以下のプログラムを考えてみたいと思います。

メソッド内の変更が、メソッド適用後にも反映されているプログラム
List<String> japanese = new ArrayList<>();
japanese.add("すぎた");
plusElementJ(japanese);
Log.d(japanese.toString());

void plusElementJ(List<String> list) {
    list.add("おはよう");
    Log.d(list.toString());
}
結果
[すぎた, おはよう]
[すぎた, おはよう]

上記のプログラムでは、一二行目で 東京都千代田区千代田1−1に皇居があることを宣言しています。
メソッドに東京都千代田区千代田1−1の住所を渡します。
メソッド内では、受け取った住所に対して、増築を行いました。
すると、メソッドをでても、東京都千代田区千代田1−1には皇居とそれを増築した結果があるのは納得できましたね。

Stringも参照型だけど。。。

メソッド内での変更がメソッド適用後に反映されていない
String name = "すぎた";
concatenate(name);
Log.d(name);

void concatenate(String name) {
    name = "おはよう、" + name;
    Log.d(name);
}
結果
after applying concatenate おはよう、すぎた
outside of method concatenate すぎた

Stringは参照型ではありますが、immutableです。つまり変更不可能です。
そのため、この処理は内部的には以下のように新しいStringオブジェクトが作られているんじゃないでしょうか?

name = new String("おはよう、"  + name)

そのため、以下のようなことが起こっていると思います。

  1. コピーされている参照値 nameには新しい参照値が代入される
  2. nameが新しく参照している参照値に新しくオブジェクトが作成される

参考

もう参照渡しとは言わせない

9
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4