この記事ではラッパークラス同士の比較を紹介します。
基本データ型を比較する際は「==」を使用し、String型などを比較する際は「equals」メソッドを利用します。
では、Integerなどのラッパークラスに関してはどうでしょうか。
まずはサンプルコードを入力します。
【IntegerComparison.java】
1 2 3 4 5 6 7 8 9 |
class IntegerComparison { public static void main(String[] args) { Integer num1 = 100; Integer num2 = 100; boolean bool = num1 == num2; System.out.println(“num1 == num2:” + bool); } } |
【実行結果】
num1 == num2:true
実行結果は想像したとおりになったのではないでしょうか。
Integer型の変数num1とnum2に整数の100を代入し比較を行っているのでtrueになると考えるかと思います。
続けて下記のようにサンプルコードを書き換えます。
【IntegerComparison.java】
1 2 3 4 5 6 7 8 9 |
class IntegerComparison { public static void main(String[] args) { Integer num1 = 300; Integer num2 = 300; boolean bool = num1 == num2; System.out.println(“num1 == num2:” + bool); } } |
【実行結果】
num1 == num2:false
Integer型の変数num1とnum2に整数の300を代入する形に変更しています。
その二つの変数を比較した結果はfalseになっています。
まず前提としてIntegerは参照型ですので「==」で比較を行うと参照アドレスの比較になり、整数の値の比較にはなりません。
ではなぜ100で比較した時はtrueで300で比較した時はfalseになるのでしょうか。
実はjava.lang.Integer.IntegerCacheというクラスがIntegerのオブジェクトをデフォルトで1バイト分(-128~127)をキャッシュするようになっているからです。
Integer型の変数に-128~127の値を代入した場合そのjava.lang.Integer.IntegerCacheクラスがキャッシュしているIntegerオブジェクトが参照されます。
つまり-128~127の値を別々の変数に代入したとしても同じ値であれば同じアドレスを参照することになります。
よって-128~127の間である100を代入したInteger同士の比較結果はtrueとなり、300を代入したInteger同士の比較結果はfalseとなるということです。
どのような値でも正しい比較結果を求める方法は複数あります。
たとえば、String型と同様equalsメソッドで比較を行う方法やnum1.intValue() == num2.intValue()で比較するなどがあります。
num1.intValue() == num2.intValue()で比較した場合はアドレスの比較ではなくIntegerオブジェクトが参照する数値同士、つまりint型の値同士の比較になるため正しく比較することができます。
下記のようなコードでもAutoboxingが働くため正しく比較ができます。
1 2 |
Integer num1 = 300; boolean bool = num1 == 300; |
また、new演算子を使いIntegerオブジェクトを生成した場合はどのような値であっても「==」を用いた比較ではfalseになりますので注意をしてください。
この記事の内容はIntegerクラスに限らすべてのラッパークラスに共通することになります。
実際にはこのような問題に直面することは少ないかもしれませんが、いざというときに知っていると役に立ちますので覚えておくようにしましょう。