Stringの参照とString Constant Pool とは?Java初心者の勉強

String(文字列型)の比較で「==」で比較する参照の比較を理解するために、いきついた「String Constant Pool」をまとめてみます。

String Constant Pool とは

String Constant Pool (略してSCPやString poolと言ってる人もいた)は日本語訳は見当たらなかったので、そのままStringコンスタントプールと呼びます。

一言で言えばヒープ領域を節約するための機能です。
String(文字列)は不変(immutable)のため不必要なオブジェクトの生成を避けます。そこでStringコンスタントプールが活用されます。
ここからはサンプルコードと、イメージを使って説明していきます。

文字列はString Constant Poolを参照する

String Constant PoolはHeap領域の中にあります。

サンプルコード

String str1 = "Hello";

解説

string_constant_pool image

上記コードで生成された文字列はヒープ領域の中にあるStringコンスタントプールへ保管されます。

ローカル変数のインターン化

同じ文字列を生成した場合の参照はどうなるでしょう。

サンプルコード

String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2); // true

解説

string_constant_pool image

ローカル変数「str1」と「str2」は同じHelloを生成しています。
一度Stringコンスタントプールに生成されたものがあれば、後から同じ文字列を生成した場合、暗黙的にインターン化(同じものを参照しよう的な)されます。そのため参照の比較はtrue(一致)となります。

Stringをnewして生成する

文字列の生成方法には他にもnewで生成する方法もありますよね。

サンプルコード

String str1 = new String("Hello");

解説

string_constant_pool image

newした場合、Stringコンスタントプールへの保管はされず、ヒープ領域へ直接保管されます。

Stringをnewして複数生成する

同じ値をnewで生成してみます。

サンプルコード

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2); // false

解説

string_constant_pool image

ヒープ領域ではStringコンスタントプールと異なりインターン化などはないため、newして生成された参照(インスタンス)が同じになることはありません。そのため参照の比較はfalse(不一致)となります。

newとnewを使わない生成

newとnewを使わない基本的な文字列の生成についでです。

サンプルコード

String str1 = new String("Hello");
String str2 = "Hello";
System.out.println(str1 == str2); // false

解説

string_constant_pool image

new String()で生成されたものはヒープ領域へ、基本的な生成はStringコンスタントプールへ保管されており、別々の参照のため参照の比較はfalse(不一致)となります。

おわり

文字列の比較はbooleanを使えばいいんだし、関係ないんだからいいかなとも思ったのですがきちんと理解したいなと思い調べだしたらなかなかいい記事が見当たらずかなり時間を要してしまいました。
いい記事にも巡りあえたし、わかってしまえばさほど難しくなかったですね。

参考

https://www.geeksforgeeks.org/string-constant-pool-in-java/

Java

Posted by Nakamoto