4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

なぜStringの値を変更しても他の変数に影響しないのか?

Posted at

1. はじめに

JavaのString型において、ある変数を別の変数に代入した後、元の変数の値を変更しても影響しないのはなぜでしょうか?
この記事では、Stringが不変オブジェクトとして設計されている理由と、代入時の挙動をわかりやすく解説します。

Sample.java
public class Sample {
    public static void main(String[] args) {
        String st1 = "Hello!";
        String st2 = st1;

        st1 = "Java";

        System.out.println(st1); // Java
        System.out.println(st2); // Hello! ← 参照型なのに影響されないのはなぜ?
    }
}

2. 結論

冒頭でもさらっと記載しましたが、
JavaのStringは不変オブジェクト(Immutable Object)として設計されているため、ある変数を別の変数に代入した後に値を変更しても、他の変数に影響を与えることはありません。

ピンときませんね。
順を追って説明します。

3. 不変オブジェクトとは

不変オブジェクトには以下のような特性があります。

  • 一度作成された文字列は変更できない。
  • 新しい値が代入されると、新しいオブジェクトが作成され、既存のオブジェクトには影響がない。

3.1. 具体例で理解するStringの代入と参照

  • 参照の挙動
Sample.java
public class Sample {
    public static void main(String[] args) {
        String st1 = "Hello!";
        String st2 = st1;        // -- ポイント1

        st1 = "Java";            // -- ポイント2

        System.out.println(st1); // Java
        System.out.println(st2); // Hello!
    }
}
  • メモリ上の挙動
    • ポイント1
      初期状態:st1st2は同じ文字列("Hello!")を参照している。
    • ポイント2
      st1 = "Java";を実行した際に、新しい文字列オブジェクト("Java")が作成される。

  • イメージ図
    スクリーンショット 2025-01-10 0.24.03.png
    スクリーンショット 2025-01-10 0.32.33.png
    スクリーンショット 2025-01-10 0.40.17.png

4. なぜStringは不変オブジェクトなのか?

  • セキュリティの理由
    • パスワードやURLなどの重要データを変更できないことで、安全性が向上。
  • スレッドセーフの理由
    • マルチスレッド環境で文字列が共有されても、状態を変更される心配がない。
  • パフォーマンスの理由
    • 文字列プールによるメモリ効率の向上。

5. Stringと他の可変オブジェクトの違い

  • 可変オブジェクトの例
    • ArrayListStringBuilder は可変(Mutable)オブジェクト。
    • これらでは、値を変更することで同じ参照に影響を与える。
  • 参照の挙動
SampleArrayList.java
public class SampleArrayList {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("Hello");
        
        ArrayList<String> list2 = list1;
        list1.add("World");
        
        System.out.println(list1); // [Hello, World]
        System.out.println(list2); // [Hello, World] ← list1を編集したがlist2にも影響あり
    }
}
  • 解説
    • list1list2は同じArrayListオブジェクトを参照しています。
    • list1.add("World")でリストに新しい要素を追加すると、list2にもその変更が反映されます。
SampleStringBuilder.java
public class SampleStringBuilder {
    public static void main(String[] args) {
        StringBuilder sb1 = new StringBuilder("Hello");
        StringBuilder sb2 = sb1;
        sb1.append(" World");
        
        System.out.println(sb1); // "Hello World"
        System.out.println(sb2); // "Hello World" ← sb1を編集したがsb2にも影響あり
    }
}
  • 解説
    • sb1sb2は同じStringBuilderオブジェクトを参照しています。
    • sb1.append()で値を変更すると、sb2にもその変更が反映されます。

6. まとめ

  • Stringは不変オブジェクトであり、新しい値の代入は新しいオブジェクトを作成する。
  • この特性により、安全で効率的な文字列操作が可能になる。
  • 一方、ArrayListStringBuilderは可変なので、内容を直接変更することで同じオブジェクトに影響を与える。
4
5
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?