【Java】値(データ)型と参照型の違いを確認する

■値(データ)型とは

int型やdouble型などの数値を示す変数には、値が直接格納されているので値(データ)型と呼ぶ。

値(データ)型の場合、変数に直接データを格納しているため、変数間で代入しても別々のデータとして保持される。

▼イメージ図

①変数(int型)aに「0」を格納し、変数(int型)bは変数aを格納する。

②変数aおよびbには、それぞれ「0」が格納されている状態

③変数bの値を「9」に変更した場合でも、
変数aおよびbは別々のデータとして判別されるため、a=0、b=9となる。

■参照型とは

配列やインスタンスしたオブジェクト示す変数は、データとして直接格納しているのではなく、参照(メモリの位置情報)が格納されている。

参照型の場合、データとして直接格納していないため、変数間で代入した場合、同じメモリ位置を共有することになるので、一方の変数で値を変更してしまうと、大元の値が変更されることとなり、共有しているもう一方の変数で参照している値も変更されてしまう。

▼イメージ図

①変数aに配列をセットし、変数bは変数aをセットする。

②変数aとbは同じメモリ位置を参照することになる。

③変数bについて配列の値を全て「0」にすると、同じメモリ情報を参照している変数aの値も変わってしまう。

■値(データ)型確認のサンプルコード

▼サンプルコード

// 初期値をセット
int a = 0;
int b;

// b = aをセット
b = a;

// 変更前の状態を出力
System.out.println("#####変更前#####");
System.out.println("a:" + a);
System.out.println("b:" + b);

// 変数bの値を変更
b = 9;

// 変更後の状態を出力
System.out.println("#####変更後#####");
System.out.println("a:" + a);
System.out.println("b:" + b);

▼実行結果

#####変更前#####
a:0
b:0
#####変更後#####
a:0
b:9

■参照型確認のサンプルコード

▼サンプルコード

import java.util.Arrays;

public class Sample {
	
	public static void main(String[] args) {
		
		// 初期値をセット(参照型)
		int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
		int b[];
		int c[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
		
		// aとbは同じ配列を参照
		b = a;
		
		// aとbとcについて全て表示(初期状態)
		System.out.println("#####初期状態#####");
		System.out.println("a:" + Arrays.toString(a));
		System.out.println("b:" + Arrays.toString(b));
		System.out.println("c:" + Arrays.toString(c));
				
		// bについて、全てを「0」に変更する
		for(int i=0; i<b.length;i++) {
			b[i] = 0;
		}
		// aとbとcについて全て表示(bを全て0にした状態)
		System.out.println("#####b=0に変更後#####");
		System.out.println("a:" + Arrays.toString(a));
		System.out.println("b:" + Arrays.toString(b));
		System.out.println("c:" + Arrays.toString(c));
		
		// bとcは同じ配列を参照
		b = c;
		
		// bについて全てを「1」に変更する
		for(int i=0; i<b.length;i++) {
			b[i] = 1;
		}
		
		// aとbとcについて全て表示(bを全て1にした状態)
		System.out.println("#####b=1に変更後#####");
		System.out.println("a:" + Arrays.toString(a));
		System.out.println("b:" + Arrays.toString(b));
		System.out.println("c:" + Arrays.toString(c));
		
	}

}

▼実行結果

#####初期状態#####
a:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
c:[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
#####b=0に変更後#####
a:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
b:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
c:[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
#####b=1に変更後#####
a:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
b:[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
c:[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

変数bについて、最初は変数aと同じ配列を参照していたため、b=0にすると変数aの値も変更されてしまう。
次に、変数bは変数cと同じ配列を参照しているため、b=1にすると変数cの値も変更されてしまう。
なお、このとき、変数bは変数aと違う配列である、変数cと同じ配列を参照している状態であるため、変数aが参照している配列の値は0のままである。

コメント