LoginSignup
1
1

More than 3 years have passed since last update.

【Java】参照値渡しという言葉が悪い!

Last updated at Posted at 2020-05-04

必ずつまづくJavaの参照値渡し

Javaにおいて、参照渡しは存在しないとよく聞きます。
最初は「えっ」って思いましたが、調べた結果をまとめました。

一般的なメソッドの引数の渡し方

・値渡し
・参照渡し
・参照値渡し

Javaにおけるメソッドの引数の渡し方

・値渡し
・参照値渡し
※「参照渡し」はJavaでは存在しません。
「値渡し」、「参照値渡し」について、説明していきます。

値渡しの例

RefValHandOver.java
private static void editNumber(int arg){
    arg = 0;
    System.out.println("editNumber : " + arg);
}
public static void main(String[] args) {
    int number = 100;
    editNumber(number);
    System.out.println( "main : " + number);
}

結果

editNumber : 0
main : 100

editNumber内では0になっているが、main内では100のままで変わらない。
引数をプリミティブ型にした場合は値渡しとなる。

プリミティブ型

bit 初期値
boolean 1bit false
byte 8bit 0
char 16bit \u0000
short 16bit 0
int 32bit 0
float 32bit 0.0
long 64bit 0
double 64bit 0.0

ここまでは特に問題ないですよね。

参照値渡しの例

3つのパターンに分類して説明していきます。
・1. メソッド内でデータ操作した場合
・2. メソッド内でnewしなおす。
・3. メソッド内でnullを代入する。

RefValHandOver.java
// 1. メソッド内でデータ操作した場合
private static void methodAddArray(ArrayList<String> arg){
    arg.add("B");
    System.out.println("methodAddArray : " + arg.hashCode() + " : " + arg.toString());
}
//2. メソッド内でnewしなおす。
private static void methodNewArray(ArrayList<String> arg){
    arg = new ArrayList<String>();
    arg.add("C");
    System.out.println("methodNewArray : " +arg.hashCode() + " : " +  arg.toString());
}
//3. メソッド内でnullを代入する。
private static void methodNullArray(ArrayList<String> arg){
    arg = null;
    System.out.println((arg != null) ? "methodNullArray : " + arg.hashCode() + " : " +  arg.toString() : "null");
}

public static void main(String[] args) {
    ArrayList<String> arrayList = new ArrayList<String>() {{add("A");}};
    // 1. メソッド内でデータ操作した場合
    methodAddArray(arrayList);
    System.out.println("main : " + arrayList.hashCode() + " : " +  arrayList.toString());

    //2. メソッド内でnewしなおす。
    methodNewArray(arrayList);
    System.out.println("main : " + arrayList.hashCode() + " : " +  arrayList.toString());

    //3. メソッド内でnullを代入する。
    methodNullArray(arrayList);
    System.out.println((arrayList != null) ? "main : " + arrayList.hashCode() + " : " +  arrayList.toString() : "null");

}

結果

// 1. メソッド内でデータ操作した場合
methodAddArray : 3042 : [A, B]
main : 3042 : [A, B]       //参照先が変わっていない

//2. メソッド内でnewしなおす。
methodNewArray : 98 : [C]
main : 3042 : [A, B]       //参照先が変わっている

//3. メソッド内でnullを代入する。
methodNullArray : null
main : 3042 : [A, B]       //参照先が変わっている 

図解してみる

参照値渡し.png

説明してみる

焦点は引数に新しい参照先を代入しているかどうかです。
代入されると「main内のローカル変数」と「メソッド内の引数」が別物になってしまいます。
※Javaには存在しない参照渡しでは2、3の例がmainのローカル変数に反映されます。

まとめ

値渡し参照値渡しについて説明してきました。
個人的には参照値渡しを参照先アドレス渡しとしたら、わかりやすいんじゃないかと思います。

1
1
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
1
1