问题描述
观察这种情况让我非常困惑:
It was very confusing to me to observe this situation:
Integer i = null;
String str = null;
if (i == null) { //Nothing happens
...
}
if (str == null) { //Nothing happens
}
if (i == 0) { //NullPointerException
...
}
if (str == "0") { //Nothing happens
...
}
所以,as我认为首先执行装箱操作(即java尝试从 null
中提取int值),并且比较操作具有较低的优先级,这就是抛出异常的原因。
So, as I think boxing operation is executed first (i.e. java tries to extract int value from null
) and comparison operation has lower priority that's why the exception is thrown.
问题是:为什么在Java中以这种方式实现?为什么拳击优先于比较参考?或者为什么他们没有在拳击前对 null
实施验证?
The question is: why is it implemented in this way in Java? Why boxing has higher priority then comparing references? Or why didn't they implemented verification against null
before boxing?
当 NullPointerException
被包装的基元抛出时,它看起来不一致,并且不会抛出 true 对象类型。
At the moment it looks inconsistent when NullPointerException
is thrown with wrapped primitives and is not thrown with true object types.
推荐答案
简答
关键点是:
The Short Answer
The key point is this:
-
==
两种参考类型之间总是参考比较
- 通常情况下,例如使用
Integer
和String
,您要使用等于
==
between two reference types is always reference comparison- More often than not, e.g. with
Integer
andString
, you'd want to useequals
instead
- 引用类型将进行拆箱转换
- 拆箱
null
总是抛出NullPointerException
- The reference type will be subjected to unboxing conversion
- Unboxing
null
always throwsNullPointerException
以上语句适用于任何给定的有效 Java代码。根据这种理解,您提供的代码段中没有任何不一致。
The above statements hold for any given valid Java code. With this understanding, there is no inconsistency whatsoever in the snippet you presented.
以下是相关的JLS部分:
Here are the relevant JLS sections:
这解释了以下内容:
Integer i = null; String str = null; if (i == null) { // Nothing happens } if (str == null) { // Nothing happens } if (str == "0") { // Nothing happens }
两个操作数是引用类型,这就是
==
是引用相等比较的原因。Both operands are reference types, and that's why the
==
is reference equality comparison.这也解释了以下内容: / p>
This also explains the following:
System.out.println(new Integer(0) == new Integer(0)); // "false" System.out.println("X" == "x".toUpperCase()); // "false"
对于
==
为了数字相等,至少有一个操作数必须是数字类型:注意二进制数字促销执行价值集转换和拆箱转换。
Note that binary numeric promotion performs value set conversion and unboxing conversion.
这解释了:
Integer i = null; if (i == 0) { //NullPointerException }
以下摘录自 Effective Java 2nd Edition,第49项:首选原语为盒装基元:
有些地方你别无选择但要使用盒装基元,例如泛型,但你应该认真考虑是否有合理使用盒装基元的决定。
There are places where you have no choice but to use boxed primitives, e.g. generics, but otherwise you should seriously consider if a decision to use boxed primitives is justified.
-
- 数字类型是整数类型和浮点类型。
- JLS 4.2. Primitive Types and Values
- "The numeric types are the integral types and the floating-point types."
- 一种类型据说是可兑换到数字类型如果是数字类型,或者它是可以通过取消装箱转换转换为数字类型的引用类型。
- 取消装箱转换会转换[ ...]从类型
整数
到键入int
- 如果
r
是null
,取消装箱转换会抛出NullPointerException
- "A type is said to be convertible to a numeric type if it is a numeric type, or it is a reference type that may be converted to a numeric type by unboxing conversion."
- "Unboxing conversion converts [...] from type
Integer
to typeint
" - "If
r
isnull
, unboxing conversion throws aNullPointerException
"
- When comparing two
Integers
in Java does auto-unboxing occur? - Why are these
==
but notequals()
? - Java: What’s the difference between autoboxing and casting?
- (是的!这个盒子是未装箱的,而不是其他方式!)
- (!!!)
- (不幸的是,是的)
- What is the difference between an int and an Integer in Java/C#?
- Is it guaranteed that new Integer(i) == i in Java? (YES!!! The box is unboxed, not other way around!)
- Why does
int num = Integer.getInteger("123")
throwNullPointerException
? (!!!) - Java noob: generics over objects only? (yes, unfortunately)
- Java
String.equals
versus==
这篇关于为什么将Integer与int进行比较可以在Java中抛出NullPointerException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
- More often than not, e.g. with
- 通常情况下,例如使用