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にあるクラスとメソッドを積極的に利用するべきである。