【初心者向け】JavaのStringとStringBuilderの違いとは? 図で理解する参照の仕組み

こんにちは、湯本です。
 
Javaでは、文字列の比較方法によって結果が異なります。特に「==」と「equals」の違いは、初心者がつまずきやすいポイントです。
 
「同じ文字列なのにfalseになるのはなぜ?」「StringBuilderはequalsで比較できるの?」このような疑問を持ったことがある方も多いのではないでしょうか。
 
この記事では、StringとStringBuilderを例に、「==」と「equals」の違いと、それぞれの比較結果について分かりやすく解説します。

StringとStringBuilderの比較方法の違いとは?

まず前提として、StringとStringBuilderには大きな違いがあります。

  • String:イミュータブル(変更不可)な文字列
  • StringBuilder:ミュータブル(変更可能)な文字列

Stringは一度生成すると内容を変更できません。一方、StringBuilderは文字列の追加や変更が可能です。
 
この違いが、比較結果にも影響します。

「==」と「equals」の違い

Javaで文字列を比較する方法は主に2つあります。

  • == :参照(オブジェクトの場所)を比較
  • equals:内容(文字列)を比較

つまり、同じ「Java」という文字列でも、比較方法によって結果が異なる場合があります。

サンプルコード

文字列「Java」をStringとStringBuilderでそれぞれ生成し、比較します。

package training;

public class StringStringBuilder {
    public static void main(String[] args) throws Exception {
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder("Java");
        sb1.append("Java");
        String s1 = "Java";
        String s2 = "Ja" + "va";
        String s3 = sb2.toString();

        System.out.println(sb1 == sb2);      // ①
        System.out.println(s1 == s2);        // ②
        System.out.println(s1 == s3);        // ③
        System.out.println(sb1.equals(sb2)); // ④
        System.out.println(s1.equals(sb1));  // ⑤
        System.out.println(s1.equals(s2));   // ⑥
        System.out.println(s1.equals(s3));   // ⑦
    }
}

実行結果

上記プログラムの実行結果は以下の通りです。

false  // ①
true   // ②
false  // ③
false  // ④
false  // ⑤
true   // ⑥
true   // ⑦

比較結果の解説(String / StringBuilder)

①sb1 == sb2
sb1とsb2は異なるStringBuilderオブジェクトを参照しています。そのため、参照を比較する「==」ではfalseになります。
 
②s1 == s2
s1とs2はどちらも文字列リテラル「Java」です。Javaでは同じリテラルは再利用され、同じオブジェクトを参照します。
 
この仕組みをインターン化(Stringインターン)と呼びます。そのため「==」の結果はtrueになります。
 
③s1 == s3
s1はリテラル、s3はStringBuilderから生成されたStringです。異なるオブジェクトのため「==」はfalseになります。
 
④sb1.equals(sb2)
StringBuilderはequalsをオーバーライドしていません。そのため、equalsでも参照比較が行われ、結果はfalseになります。
 
⑤s1.equals(sb1)
StringとStringBuilderは異なる型のため、equalsの結果はfalseです。
 
⑥s1.equals(s2)
文字列の内容が同じ「Java」のため、equalsではtrueになります。
 
⑦s1.equals(s3)
s3はStringBuilderから生成されたStringですが、内容は同じです。そのためequalsの結果はtrueになります。

図で理解する(参照と内容の違い)

よくあるミス

  • 文字列の比較に「==」を使ってしまう
  • StringBuilderでもequalsで内容比較できると思ってしまう
  • インターン化の影響で「==」がtrueになるケースを誤解する

特に「たまたまtrueになった」ケースに引きずられるのは危険です。文字列比較では「==」ではなくequalsを使用することで、意図しない比較ミスを防ぐことができます。

まとめ

「==」は参照(オブジェクトの場所)を比較し、「equals」は内容(文字列)を比較します。この違いを理解していないと、同じ文字列であっても意図しない比較結果になる可能性があります。特に文字列比較では「==」ではなくequalsを使用することが重要です。これにより、比較ミスによるバグを防ぐことができます。
 
StringとStringBuilderではequalsの挙動も異なるため、用途に応じて適切に使い分けることが、正確で安全なプログラムを書くためのポイントです。
 
 
 
 
《関連記事》

JavaのString.formatの使い方
技術
2025.3.14(Fri)

文字列を整形できる! JavaのString.formatの使い方

#まとめ#Java

Javaの列挙型「enum」を徹底解説
技術
2025.4.16(Wed)

Javaの列挙型「enum」を徹底解説! 定数を分かりやすく管理する方法

#まとめ#プログラム#Java

Javaのabstractクラスとは
技術
2026.6.25(Thu)

Javaのabstractクラスとは? 使い方を具体例でわかりやすく解説【初心者・Bronze対策】

#Java#技術

記事をシェア
MOST VIEWED ARTICLES