Javaのオートボクシングでの注意

Javaでオートボクシングされた値に対して==!=演算子を使用する場合期待した結果にならない場合があるため注意。

以下の検証コードとその結果を示す。

public static void main(String[] args){
    for(Integer i = 126; i < 130; i++){
        for(Integer j = 126; j < 130; j++){
            System.out.println("i:" + i + ", j:" + j + ", i==j:" + (i==j));
        }
    }
}
i:126, j:126, i==j:true
i:126, j:127, i==j:false
i:126, j:128, i==j:false
i:126, j:129, i==j:false
i:127, j:126, i==j:false
i:127, j:127, i==j:true
i:127, j:128, i==j:false
i:127, j:129, i==j:false
i:128, j:126, i==j:false
i:128, j:127, i==j:false
i:128, j:128, i==j:false // ★
i:128, j:129, i==j:false
i:129, j:126, i==j:false
i:129, j:127, i==j:false
i:129, j:128, i==j:false
i:129, j:129, i==j:false // ★

をつけた行で比較の結果がtrueとなっていないことがわかる。これは、Integerクラスでは、-128から127の範囲のみ値がキャッシュされるからである。

-128から127の範囲のみで動作確認を行い、範囲外のデータが来たときに想定外の挙動とならないよう、そもそもInteger型変数同士を==!=演算子で比較しないように気をつけたほうが良い。
比較を行う場合、

Objects.equals(i, j)

のように比較用のメソッドを利用するか、

i.intValue() == j.intValue()

のようにint型にアンボクシングしてから比較するのが良い。

参考ページ(https://www.jpcert.or.jp/java-rules/exp03-j.html)