String クラスを生成する際は String a = new String("name"); // A String b = "name"; // B String c = "name"; // C の2種類の方法がある。見た目は大して変わりなさそうだが、実際はこの2つの動作は異なる。 A は new しているため文字列の内容に関わらず必ずStringインスタンスが生成される。もちろんメモリが消費される。 B も1度目はStringインスタンスが生成されるが、C 実行時にプールに"name"が存在するため b と同じインスタンスを参照する。つまりメモリを節約できる。特に問題が無ければ B,Cの方法で記述した方がいいだろう。
[StringInstance.java]
/**
* Stringクラス生成とメモリ テストクラス
*/
public class StringInstance {
public static void main(String[] args) {
// String インスタンスを生成
// 同時にコンパイラが "name" をプールに追加
String s1 = "name";
// 既に "name" がプールに存在するためStringを生成せずに
// 既存インスタンス(s1)を参照
String s2 = "name";
// String インスタンス生成
String s3 = new String("name");
// String インスタンス生成
String s4 = new String("name");
System.out.println("s1(name) == s2(name) : " + (s1 == s2));
System.out.println("s3(uma) == s4(uma) : " + (s3 == s4));
System.out.println("s1(name) == new StringSub1.str(name) : " + (s1 == (new StringSub1()).str));
System.out.println("s1(name) == StringSub2.str(name) : " + (s1 == StringSub2.str));
System.out.println("s1(name) == StringSub3.str(name) : " + (s1 == StringSub3.str));
}
}
class StringSub1 {
public String str = "name";
}
class StringSub2 {
public static final String str = "name";
}
「StringSub3.java]
public class StringSub3 {
public static final String str = "name";
}
実行結果
s1(name) == s2(name) : true
s3(uma) == s4(uma) : false
s1(name) == new StringSub1.str(name) : true
s1(name) == StringSub2.str(name) : true
s1(name) == StringSub3.str(name) : true