🧠【初心者向け】String Pool をやさしく解説(図解あり)
Java の文字列は、他のオブジェクトとは少し違う特別な扱いを受けています。
その中心にあるのが String Pool(文字列プール) という仕組みです。
「String はなぜ不変なの?」
「同じ文字列リテラルが再利用されるってどういうこと?」
「new String(“abc”) と “abc” の違いは?」
そんな疑問に答えるため、
この記事では “初学者でも直感的に分かる図解” を交えながら、
String Pool の仕組みと実務への影響を整理します。
結論
・文字列リテラルは、すべて String Pool に保存・再利用される
・new String(“abc”) は Pool を使わず Heap に新規生成
・String が不変(immutable)なのは、Pool を安全に再利用するため
String Pool とは?
Java が JVM レベルで保持している “重複しない文字列の倉庫” です。
🔹図解(短線版)
String Pool
┌───────┐
│ "Hello" │ ← リテラルはここに保存
│ "World" │
│ "ABC" │
└───────┘
Java はリテラル文字列を Pool に保存し、
同じ内容のリテラルが出てきた場合は 再利用 します。
なぜリテラルは再利用されるのか?(基礎)
理由は メモリ削減とパフォーマンス向上。
String a = "hello";
String b = "hello";
a と b はどちらも Pool 内の 同じ “hello” を共有 します。
a ──▶ "hello" ◀── b
一度作った文字列を何度も再生成するのは無駄だからです。
new String(“abc”) が Pool を使わない理由
String s = new String("abc");
これは Heap に新しく文字列オブジェクトを作る 行為です。
図にするとこう👇
"abc"(String Pool)
↑
new String("abc")
↓
Heap に新規オブジェクト
つまり:
- Pool → あくまでもリテラル用
- new → 必ず別オブジェクトを作る
String が不変(immutable)な理由
String が不変であることで以下が可能になります👇
- Pool 内の文字列を 安全に共有
- “破壊的変更” が起きないので スレッドセーフ
- HashMap のキーなどで ハッシュ値が変わらない
もし String が可変だったら:
a → "abc"
b → "abc"
a が "xyz" に書き換わると b も変わってしまう
→ 破滅。
だから String は 不変である必要がある のです。
ここまでのまとめ(初心者向け)
- リテラルは String Pool に保存され再利用
- new String() は Pool を使わない
- String が不変なのは Pool 共有・安全性のため
- Pool を理解すると “文字列の挙動” が一気に読みやすくなる
▼▼ ここから深掘り・ニッチ編 ▼▼
【後半:ニッチ編】String Pool の内部構造と JVM の動き
intern() メソッドの本当の役割
intern() を使うと:
- その文字列と同じ内容の文字列が Pool にある → それを返す
- なければ 現在の文字列を Pool に登録して返す
String s = new String("hello");
String p = s.intern();
図で示すと👇
Pool: "hello"
↑
p ───┘
s(Heap)…別オブジェクト
つまり Heap → Pool の参照に切り替えるためのもの。
String Pool はどこに存在する?(JVM視点)
Java 7 以降、String Pool は Heap 上に配置 されています。
(Java 6 以前は PermGen 領域)
理由:
- PermGen が小さすぎて OOM を起こしやすかった
- Pool を Heap に置いたほうが管理しやすい
図解(短線版)
Heap
├ String Pool
│ ├ "A"
│ ├ "B"
│ └ "C"
└ 他のオブジェクト
パフォーマンス・メモリ観点での注意事項
✔ 大量の文字列を扱う場合
StringBuilder / StringBuffer を使うほうが効率的。
✔ Pool の使いすぎに注意
普通に使う分には問題ないが、
大量の intern() 連発は Heap を圧迫することがある。
✔ new String() を避ける
無駄にオブジェクトを増やすため、基本的には不要。
スレッド安全性との関係
Pool 内の文字列は 不変なのでスレッドセーフ。
ただし:
- Pool の遅延登録(intern動作)には内部ロックがある
- 同時大量 intern はスケールしにくい
実務ではあまり問題にならないが知識として重要。
この記事のまとめ
- String Pool は Java の文字列再利用の中核
- リテラルは Pool、new は Heap
- immutable である理由は “共有の安全性”
- intern() は Heap→Pool の参照統一に使う
- パフォーマンスや GC の理解にもつながる
Deep Friendly Tech の一言(後書き)
String Pool は、
「Java がなぜ安全で効率的なのか?」
という根本を支える存在です。
文字列はアプリケーションで最も使われるデータ型。
だからこそ、その裏側の仕組みを知っていると
コードの質・読み解く力・パフォーマンス理解 が一段アップします。

コメント