JavaのStringは文字の並び(シーケンス)を表すオブジェクトであり、プリミティブ型ではありません。
java.langパッケージに含まれるStringクラスを使用します。StringクラスはObjectを継承し、toString()メソッドをオーバーライドして内容を返すようになっています。
Stringの生成方法
1.リテラルを使用
String name1 = "abc"; String name2 = "xyz";
同じ値がすでに存在する場合は、String Pool内の既存オブジェクトを参照します。
2.newキーワードを使用
String name = new String("abc");
常にヒープ上に新しいオブジェクトを作成します。
String Poolの既存オブジェクトとは別物です。
String Poolとは?
Javaには「同じ文字列を何度も作らないようにする仕組み」があり、これがString Pool(文字列プール)です。
- String Poolは「同じ文字列を1つだけ保存して共有する仕組み」です。
- intern()を使うと、ヒープ上の文字列をプール内の文字列に変換できます。
- リテラル文字列は自動でプールに入ります。
String s1 = new String("hello"); String s2 = s1.intern(); String s3 = "hello"; System.out.println(s2 == s3); // true
- s1はnewで作ったのでヒープ上に新しいオブジェクトとして生成されます。
- s2 = s1.intern()で、文字列プール(String Pool)にある "hello" を参照するようになります。
- s3はリテラルなので、自動的に文字列プール内の "hello" を参照します。
- そのため s2 == s3 は true になります。
- == は参照先(メモリ上の場所)が同じかどうかを比較するため、両方とも文字列プールの同じオブジェクトを指しているからです。
Stringの性質
イミュータブル(不変)
文字列は厳密には変更できません。変更すると新しいStringインスタンスが生成されます。
String original = "abc"; String modified = original.concat("def"); System.out.println(original); // "abc" System.out.println(modified); // "abcdef"
参照比較と値比較
String a = "hello"; String b = "hello"; System.out.println(a == b); // true → 同じString Pool String c = new String("hello"); System.out.println(a == c); // false → ヒープ上の別オブジェクト System.out.println(a.equals(c)); // true → 内容は同じ
代表的なメソッド
メソッド | 説明 |
---|---|
length() |
文字列の長さを取得 |
charAt(int) |
指定位置の文字を取得 |
substring(int, int) |
部分文字列を抽出 |
equals() |
内容を比較 |
equalsIgnoreCase() |
大文字小文字を無視して比較 |
compareTo() |
辞書順比較 |
toUpperCase() / toLowerCase() |
大文字/小文字変換 |
trim() |
前後の空白を削除 |
replace(old, new) |
文字の置換 |
replaceAll(regex, replacement) |
正規表現による置換 |
split(String regex) |
分割して配列に変換 |
contains(CharSequence) |
部分文字列を確認 |
startsWith() / endsWith() |
先頭/末尾の確認 |
intern() |
String Poolの参照を返す |
まとめ
- Stringは文字列を扱う基本オブジェクトで、イミュータブルであることが最大の特徴です。
- リテラルとnewによる生成の違いや、==と.equals()の使い分けを理解することが重要です。
- 代表的メソッドを押さえることで、文字列操作を効率的に行えます。