【Java】Stringクラスの文字列比較
今日はJavaのStringクラスについて。JavaのStringの文字列比較について知らなかったことがあるので紹介します。
[目次]
1. Stringクラスによる文字列比較
Javaにおいて、Stringクラスの文字列比較は「==」ではなく、「equals()メソッド」を使いましょう。なぜなら、「==」は比較対象の二つの文字列変数が同じオブジェクトへの参照かどうかを判定するのに対し、「equals()メソッド」は文字列の内容が一致しているかを判定するからです。
と言われます。
では、下記のプログラムを実行すると、結果はどうなるでしょうか?
public class StringTest { public static void main(String[] args) { String hoge1 = "hogehoge"; String hoge2 = "hogehoge"; if (hoge1 == hoge2) { System.out.println("Equal"); } else { System.out.println("Not Equal"); } } }
結果は、、、
Equal
となります。
なぜかというと、JavaにはString Poolと呼ばれる文字列がJVMによって格納される特別なメモリ領域があるためです。
2. String Pool
String型の変数を作成してそこに文字列リテラルを代入すると、まずString Pool内に同じ文字列が存在しないか検索されます。
そこで同じ文字列が見つかった場合は、その文字列への参照を返します。
見つからなかった場合は、String Poolに文字列を格納して、その参照が返されます。
つまり、上記のプログラムの例ではString Pool内に存在する「hogehoge」という文字列オブジェクトへの参照が、「hoge1」と「hoge2」へ返されるため、「==」で比較したときに同じオブジェクトへの参照と判定されて「Equal」となるということです。
String Pool内で使用された文字列を重複なく管理して、同じ値の文字列がString Poolに存在した場合はそのインスタンスへの参照を返すことで、オブジェクトが無駄に作成されることを防ぐことができるということです。
2.1. immutable(イミュータブル)なクラス
ここで、同じ参照値が使いまわされるとすると、インスタンスの中身が書き換えられてしまった場合の懸念があります。
たとえば、変数Aと変数Bが同じインスタンスへの参照値を保持しているとします。このとき、変数Bからインスタンスの中身を書き換えられてしまうと、変数Aにも影響が出てしまうのでは?ということです。
そしてこれは、immutable(イミュータブル)なクラスが解決します。
イミュータブルなクラスは、オブジェクト自体の値を書き換えられないようになっているクラスなんです。
JavaのStringはイミュータブルなクラスなので、String Poolから参照が返されても、その値を書き換えることは不可能ということです。
3. new String()
Stringクラスは、String Poolに同じ文字列があればその参照が返されると説明しましたが、new String()でStringクラスをインスタンス化したときはString Poolは考慮されません。
new String()でインスタンス化すると、文字列オブジェクトが新規で作成されます。
よって、下記のプログラムを実行すると「No Equal」が表示されます。
public class StringTest { public static void main(String[] args) { String hoge1 = "hogehoge"; String hoge2 = new String("hogehoge"); if (hoge1 == hoge2) { System.out.println("Equal"); } else { System.out.println("Not Equal"); } } }
4. まとめ
JavaのStringクラスの文字列比較ついてまとめてみました。文字だらけで長くなってしまいましたが、Stringの理解の手助けになれば幸いです。
参考
- Java文字列のプール: https://www.codeflow.site/ja/article/java-string-pool
- クラスString : https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html
- 谷本心/阪本雄一郎/岡田拓也/秋葉誠/村田健一郎 「Java 本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで」 株式会社技術評論社
- 7-1-1 Stringクラスの特徴
- Joshua Bloch著 「Effective Java 第2版」 丸善出版
- 第2章 項目5 不要なオブジェクトの生成を避ける