javaのオブジェクト型(Integer)を==比較すると危険!

java

javaにはオブジェクト型とプリミティブ型の変数があります。
オブジェクト型で==を使うと予期せぬ動きをする場合があります。

数値を比較する場合は、プリミティブ型は==を使って、
オブジェクト型はequalsを使うようにしましょう。

今回はどのような落とし穴があるのかについて紹介します。

[スポンサーリンク]

典型的なダメパターン

このパターンは、皆さんもよくご存じだと思います。
newインスタンス化したオブジェクト同士の比較です。
結果は予想通り、「等しくない」です。
これはオブジェクトのアドレスを比較していることが原因ですね。

        Integer int1 = new Integer("1");
        Integer int2 = new Integer("1");
        if ( int1 == int2) {
            System.out.println("等しい");
        } else {
            System.out.println("等しくない");
        }

実行結果

>実行結果
等しくない

==比較がOKなパターン

newインスタンスをせずに、直接数値を入れたパターンです。
これは、「等しい」です。
java5から登場しました、オートボクシングによって、java内部でInteger.valueOf(1)に自動変換してくれているので、==比較が可能となります。

        Integer int3 = 1;
        Integer int4 = 1;
        if ( int3 == int4) {
            System.out.println("等しい");
        } else {
            System.out.println("等しくない");
        }

実行結果

>実行結果
等しい

==比較がNGなパターン

先ほどと同じで数値を直接入れるパターンです。
結果は、「等しくない」です。
これは予想と反したのではないでしょうか?

これは、-128から127までの間の数値は、java内部で同一オブジェクトが使われて、Integer.valueOf(1)に自動変換してくれます。
しかし、-128から127の範囲外は、new Integer(1)で別オブジェクトへインスタンス化されるため、==比較ではNGとなります。

        Integer int5 = 128;
        Integer int6 = 128;
        if ( int5 == int6) {
            System.out.println("等しい");
        } else {
            System.out.println("等しくない");
        }

実行結果

>実行結果
等しくない

まとめ

Integerに直接数値を入れるパターンは、
-128から127までの間の数値は、==で比較OKです。
-128から127の範囲外は、==で比較NGです。
数値の大きさによってif判定も変わってくるので、Integerオブジェクトを==比較するのはやめましょう!

最後に

以上が、オブジェクト型(Integer)を==で比較することのリスクです。
数値の幅によってプログラムがある日突然動かなくなることがあります。
テストも終わって本番環境に乗せたら・・・・。なんてことになる前にしっかりと予防しましょう!
それでは!