Java入門 値渡しと参照渡し
本記事は、Javaを一から学んでいく際の学習メモとして書かれています。
主にインプレスから出版されている「スッキリわかるJava入門 第2版 (スッキリシリーズ)」の内容に沿ったかたちで学習していきます。
今回は、Javaの値渡しと参照渡しについて学んでいきます。
値渡し
int
型のような基本データ型(プリミティブ型)で宣言された変数の値を、あるメソッドに引数として渡す場合は、メソッドの仮引数にコピーされた値そのものが渡され、メソッド内でその変数値を変更しようとしても、呼び出し元の実引数である変数には影響しません。
public class PassByValue{ public static void swap(int a, int b){ int tmp = a; a = b; b = tmp; } public static void main(String[] args) { int a = 1; int b = 2; swap(a, b); System.out.printf("a=%d\n", a); // a=1 System.out.printf("b=%d\n", b); // b=2 } }
参照渡し
ところが、配列などの参照型と言われるオブジェクトでは、コピーされた値が渡されるのではなく、その先頭アドレスへの参照値が仮引数にコピーされます。
そのため、メソッド内で仮引数にコピーされた参照値を用いて、その中身を操作することが可能です。
public class PassByReference{ public static void change(int[] array){ array[0] = 100; } public static void main(String[] args) { int[] array = {1}; change(array); System.out.printf("array[0]=%d\n", array[0]); // array[0]=100 } }
しかし、メソッド内の仮引数に別のオブジェクトを代入などをした場合は、仮引数が指すオブジェクトへの参照が変更されるのみで、呼び出し元の実引数が参照するアドレスは変更されません。
public class PassByReference{ public static void change(int[] array){ int[] newArray = {100}; array = newArray; } public static void main(String[] args) { int[] array = {1}; change(array); System.out.printf("array[0]=%d\n", array[0]); // array[0]=1 } }
String型と参照
String
型も参照型と呼ばれるもので、オブジェクト内部としてはC言語のようにchar
型の配列として扱っています。
通常は配列などのnew
キーワードで作成したオブジェクトはヒープ領域に存在しますが、String
型オブジェクトについてはその作成方法で若干異なるようです。
public class Reference{ public static void main(String[] args) { String str1 = "hello"; String str2 = new String("hello"); System.out.println(str1 == "hello"); // true System.out.println(str2 == "hello"); // false } }
上記の場合、str1
はconstant pool領域に作成され、str2
はヒープ領域に作成されます。
参照型を==
で比較するということは、保持している先頭アドレスを比較していることになるので、str1
では真、str2
では偽となります。
また、String型はイミュータブル(変更不可)なオブジェクトのため、文字列自体を書き換えることはできません。
最後に
今回はJavaの値渡しと参照渡しについて、基本的なルールを学びました。
次回はJavaで扱うパッケージについて学んでいきます。
参考書籍