短い答え
重要な点はこれです:
==
2つの参照型の間は常に参照比較です
- 多くの場合、たとえば、
Integer
とString
を使用すると、equals
代わりに使用する必要があります
==
参照型と数値プリミティブ型の間は常に数値比較です
- 参照型は開封変換の対象になります
- 開封は
null
常にスローしますNullPointerException
- Javaには多くの特別な処理が
String
ありますが、実際にはプリミティブ型ではありません。
上記のステートメントは、任意の有効なJavaコードに当てはまります。この理解により、提示したスニペットに矛盾はまったくありません。
長い答え
関連するJLSセクションは次のとおりです。
等式演算子のオペランドが両方とも参照型またはnull型の場合、演算はオブジェクトの等式です。
これは次のことを説明しています。
Integer i = null;
String str = null;
if (i == null) {
}
if (str == null) {
}
if (str == "0") {
}
両方のオペランドは参照型であるため、==
は参照の等価性の比較です。
これはまた次のことを説明します:
System.out.println(new Integer(0) == new Integer(0));
System.out.println("X" == "x".toUpperCase());
==
数値が等しいためには、オペランドの少なくとも1つが数値型である必要があります。
等式演算子のオペランドが両方とも数値型である場合、または一方が数値型であり、もう一方が数値型に変換可能である場合、2進数値の昇格がオペランドに対して実行されます。オペランドのプロモートされたタイプがまたはのint
場合long
、整数の等価性テストが実行されます。プロモートされた型がfloat or
double`の場合、浮動小数点等価性テストが実行されます。
2進数の昇格は、値セット変換とボックス化解除変換を実行することに注意してください。
これは説明します:
Integer i = null;
if (i == 0) {
}
これは、Effective Java 2nd Editionのアイテム49からの抜粋です:ボックス化されたプリミティブよりもプリミティブを優先します:
要約すると、選択できる場合は常に、ボックス化されたプリミティブよりもプリミティブを使用します。プリミティブ型はより単純で高速です。ボックス化されたプリミティブを使用する必要がある場合は、注意してください。自動ボクシングは、ボックス化されたプリミティブを使用することの冗長性を軽減しますが、危険性は軽減しません。プログラムが2つのボックス化されたプリミティブを==
演算子と比較するとき、それはID比較を行いますが、これはほぼ確実にあなたが望むものではありません。プログラムがボックス化されたプリミティブとボックス化されていないプリミティブを含む混合型の計算を行う場合、ボックス化解除を行い、プログラムがボックス化解除を行う場合、をスローする可能性がありNullPointerException
ます。最後に、プログラムがプリミティブ値をボックス化すると、コストがかかり、不要なオブジェクトが作成される可能性があります。
ジェネリックなど、ボックス化されたプリミティブを使用せざるを得ない場所もありますが、それ以外の場合は、ボックス化されたプリミティブを使用する決定が正当化されるかどうかを真剣に検討する必要があります。
参考文献
関連する質問
関連する質問