マイナー・マイナー

隠れた名作の発掘が生きがい。

同一の文字列リテラルを持つStringオブジェクトを作成する際の注意


スポンサードリンク

Stringクラスのオブジェクトを作成する記述方法には次の2つがあります.
(1) new演算子を用いた方法
(2) 文字列リテラルのみを用いた方法


例えば,"A"という文字列を表すStringオブジェクトを作る場合,上記はそれぞれ次のように記述します.

String string1 = new String("A"); //(1)
String string2 = "A"; //(2)


しかし,(1)と(2)では生成されるオブジェクトには次のような違いがあります.
(1) 常に新しいStringオブジェクトが生成される.
(2) 常に新しいStringオブジェクトが生成されるとは限らない.


特に同一な文字列を生成する場合に注意が必要です.例えば,"A"というStringオブジェクト(a1)を生成した後,"A"というオブジェクト(a2)を生成する事を考えたとき,a1,a2とも(1)の方法で作成するとa1,a2は別のオブジェクトとなりますが,a1,a2を(2)の方法で作成すると,a1とa2は同一のオブジェクトとなります.


Stringオブジェクトの等しさを確認するプログラムを次のように作成しました."A"を表すStringオブジェクトを(1)と(2)の方法でそれぞれ2つずつ作成し,それらをオブジェクト自体(アドレス)の等しさを確認する「==」演算子で比較しました.結果は,(2)の方法で作成した2つのStringオブジェクトは等しくなりました.

public class StringTest {

	public static void main(String[] args) {
		String string1_1 = new String("A");
		String string1_2 = new String("A");
		String string2_1 = "A";
		String string2_2 = "A";
		
		System.out.println(string1_1==string1_2);
		System.out.println(string1_1==string2_1);
		System.out.println(string2_1==string2_2);
	}
}


実行結果


false
false
true


上記のプログラムで作成されたStringオブジェクトは「string1_1」「string_1_2」「string2_1またはstring2_2」の3つとなります.また,作成した"A"という文字列は3つ作成されることはなく,コンスタントプールと呼ばれる領域に1つだけ作成されるそうです.「string1_1」「string_1_2」「string2_1またはstring2_2」はその1つの"A"を参照する仕組みとなっており,それによってメモリを節約しています.