Javaの値を比較する場合において、等値演算子とjava.lang.Object#equals(Object)メソッド、java.util.Objects#equals(Object, Object)メソッドの挙動の違いをまとめた。
今回は話を簡単にするため、値を整数(intとInteger)に限定した。
等値演算子
Left == Right | Left | ||||||
---|---|---|---|---|---|---|---|
null | int[1] | int[1024] | Integer[null] | Integer[1] | Integer[1024] | ||
Right | null | true | Compile Error | Compile Error | true | false | false |
int[1] | Compile Error | true | false | NullPointerException | true | false | |
int[1024] | Compile Error | false | true | NullPointerException | false | true | |
Integer[null] | true | NullPointerException | NullPointerException | true | false | false | |
Integer[1] | false | true | false | false | true | false | |
Integer[1024] | false | false | true | false | false | false |
java.lang.Integer#equals(Object)
Left.equals(Right) | Left | ||||||
---|---|---|---|---|---|---|---|
null | int[1] | int[1024] | Integer[null] | Integer[1] | Integer[1024] | ||
Right | null | Compile Error | Compile Error | Compile Error | NullPointerException | false | false |
int[1] | Compile Error | Compile Error | Compile Error | NullPointerException | true | false | |
int[1024] | Compile Error | Compile Error | Compile Error | NullPointerException | false | true | |
Integer[null] | Compile Error | Compile Error | Compile Error | NullPointerException | false | false | |
Integer[1] | Compile Error | Compile Error | Compile Error | NullPointerException | true | false | |
Integer[1024] | Compile Error | Compile Error | Compile Error | NullPointerException | false | true |
等値演算子とjava.lang.Integer#equals(Object)を比較
- 左辺がnullまたはプリミティブの場合は、equalsメソッドを呼ぶことができないためコンパイルエラーとなる。
- 左辺がObject[null]の場合、equalsメソッドを呼び出すことはできるが、実行時にNullPointerExceptionとなる。
- 1 == Object[null]の場合は、実行時に右辺がUn-Boxingされた結果、NullPointerExcpetionが発生する。
- Object[1024] == Object[1024]の結果がfalseとなっているのは、オブジェクトの同一を比較しているためである。比べて、Object[1024].equals(Object[1024])がtrueなのは、Integer#Equals(Object)によって、同値の比較処理が行われているため、正しい評価結果となる。
- Object[1] == Object[1]がtrueとなっているのは、Integerが128までのObjectをキャッシュして保持しているためであり、同一オブジェクトと評価されtrueとなる。
java.util.Objects#equals(Object, Object)
Objects.equals(Left, Right) | Left | ||||||
---|---|---|---|---|---|---|---|
null | int[1] | int[1024] | Integer[null] | Integer[1] | Integer[1024] | ||
Right | null | true | false | false | true | false | false |
int[1] | false | true | false | false | true | false | |
int[1024] | false | false | true | false | false | true | |
Integer[null] | true | false | false | true | false | false | |
Integer[1] | false | true | false | false | true | false | |
Integer[1024] | false | false | true | false | false | true |
等値演算子(==)およびjava.lang.Object#equals(Object)に比べて、期待した結果となっている。
まとめ
オブジェクトに対して、等値演算をする場合は、java.util.Objects#equals(Object, Object)を利用することをお勧めする。
等値演算だけでなく、演算処理をする場合、Objectクラスのメソッドを呼び出す場合など、java.utilやorg.apache.commons.lang3にあるクラスとメソッドを積極的に利用するべきである。