Stringインスタンスの生成方法
通常、インスタンスはnew演算子を使用して生成します。
Object obj = new Object();
しかし、Stringインスタンスは「””」で文字列を囲うだけでStringインスタンスを生成することができます。
String str = "SAMPLE";
もちろん、new演算子を使用してインスタンス生成することも可能です。
String str = new String("SAMPLE");
コンスタントプールという仕組み
「”文字列”」という記述でStringインスタンス(文字列リテラル)を生成した場合、
「コンスタントプール」というメモリ領域にStringインスタンス(文字列リテラル)が生成されます。
プログラム中ではStringインスタンス(文字列リテラル)が多く出現しますが、その度にメモリ領域にStringインスタンス(文字列リテラル)を生成していると、メモリ領域は圧迫され、リソースの負荷が高まるばかりです。
そのため「”文字列”」という記述で生成されたStringインスタンス(文字列リテラル)は、通常のインスタンスが利用するメモリ空間とは別のメモリ空間(=コンスタントプール)に作成されることになります。
そして「”文字列”」の記述によって生成されたStringインスタンス(文字列リテラル)が既にコンスタントプールに存在する場合、そのStringインスタンス(文字列リテラル)への参照が再利用されることになります。
このように、コンスタントプールを利用し無駄なメモリ消費を抑えることで、リソースを効率的に使うことができます。
例題
それでは、上記を踏まえて試験問題を解いてみましょう。
以下コードを実行した際、出力結果はどうなるでしょう。 String a = "sample"; String b = "sample"; String c = new String("sample"); System.out.println( a == b ); System.out.println( a == c ); System.out.println( a.equals(b) ); System.out.println( a.equals(c) );
正解は以下の通りです。
以下コードを実行した際、出力結果はどうなるでしょう。 String a = "sample"; String b = "sample"; String c = new String("sample"); System.out.println( a == b ); ⇒ true コンスタントプールのStringインスタンス(文字列リテラル)への参照が再利用されるので、aとbが保持しているインスタンスのアドレス値は同じになります。 System.out.println( a == c ); ⇒ false new演算子によってStringインスタンスを生成した場合、コンスタントプールは利用されません。よって、aとcが保持しているインスタンスのアドレス値は異なります。 System.out.println( a.equals(b) ); ⇒ true Stringクラスのequalsメソッドは「同じ文字列リテラルかどうか」で判定を行います。 aとbが参照しているインスタンスは同じ文字列リテラル「sample」を保持しているため、trueが返されます。 System.out.println( a.equals(c) ); ⇒ true Stringクラスのequalsメソッドは「同じ文字列リテラルかどうか」で判定を行います。 aとcが保持するインスタンスのアドレス値は異なりますが、 参照するインスタンスが保持する文字列リテラルは「sample」で同じであるため、trueが返されます。
まとめ
- 「”文字列”」の記述でStringインスタンスを生成すると、コンスタントプールにインスタンスが生成される
- コンスタントプールにStringインスタンスが生成される場合、同じ文字列リテラルを持つStringインスタンスが既に存在するなら、そのStringインスタンスが再利用される
- new演算子によってStringインスタンスを生成した場合、コンスタントプールは利用されない
- Stringクラスのequalsメソッドは「同じ文字列リテラルかどうか」で判定を行う
コメント