技術メモ

神奈川在住のITエンジニアの備忘録。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

Javaのプリミティブ型のラッパーオブジェクトはイミュータブル

整数の入ったリストを加算する場合、普段、以下のようなコードを書いている。

        // リストから一個一個取り出して、加算して戻す。
        List<Integer> numlist = new ArrayList<>(Arrays.asList(1, 2, 3));
        for (int i = 0; i < numlist.size(); i++) {
            int num = numlist.get(i);
            numlist.set(i, num + 1);
        }
        for (Integer num : numlist) {
            System.out.print(num + " "); // -> 2, 3, 4
        }

もっと簡単に書けないものかと思い、以下を試してみたが、意図通りにはならなかった。(加算されなかった。)

        // リストの要素から取り出して、そのまま加算する。
        List<Integer> numlist1 = new ArrayList<>(Arrays.asList(1, 2, 3));
        for (Integer num : numlist1) {
            num += 1;
        }
        for (Integer num : numlist1) {
            System.out.print(num + " "); // -> 1, 2, 3
        }

デバッガで見てみると分かるが、加算した時点で新しい Integer オブジェクトが自動的に作成されている。つまり、元のリストの Integer オブジェクトは何も変更されていない。
これは、Integer のような Javaのプリミティブ型のラッパーオブジェクトはイミュータブル(不変)なので、そのものは変更できないためである。

〇参考
https://www.javaworld.com/article/2077343/java-s-primitive-wrappers-are-written-in-stone.html
http://www.kab-studio.biz/Programing/JavaA2Z/Word/00001115.html