基本型
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)
そのため、以下のようなことが起こっていると思います。
- コピーされている参照値
name
には新しい参照値が代入される -
name
が新しく参照している参照値に新しくオブジェクトが作成される