Engineering Note

プログラミングなどの技術的なメモ

Java入門 値渡しと参照渡し

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

 

上記の場合、str1constant pool領域に作成され、str2ヒープ領域に作成されます。

参照型を==で比較するということは、保持している先頭アドレスを比較していることになるので、str1では真、str2では偽となります。

 

また、String型はイミュータブル(変更不可)なオブジェクトのため、文字列自体を書き換えることはできません。

 

最後に

今回はJavaの値渡しと参照渡しについて、基本的なルールを学びました。

次回はJavaで扱うパッケージについて学んでいきます。

 

参考書籍

スッキリわかるJava入門 第2版 (スッキリシリーズ)