java - 在Java中,为什么比较整数和整数可以抛出?

  显示原文与译文双语对照的内容
72 0

观察这种情况让我非常困惑:

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
. . .
}

因此,我认为装箱操作首先执行( 例如 。java尝试从 null 中提取int值,比较操作具有较低的优先级,这就是抛出异常的原因。

问题是:为什么它在Java中以这种方式实现?为什么装箱具有更高优先级,然后比较引用?还是他们在装箱之前没有针对 null 实施验证?

此时,当用包装的基元抛出 NullPointerException 并且没有用 true 对象类型抛出时,看起来不一致。

时间:原作者:0个回答

116 1

简短的答案

关键是:

  • 两个引用类型之间的== 始终是引用比较
    • 通常情况下,比如 使用 IntegerString,你希望使用 equals
  • 引用类型和数值基元类型之间的== 始终是数值比较
    • 引用类型将受到取消装箱转换的影响
    • 取消装箱 null 总是引发 NullPointerException
  • Java对 String 有许多特殊处理,实际上它不是基本类型

上面的语句适用于任何给定的有效的Java代码。通过这种理解,你所提供的代码Fragment中没有任何不一致。

长答案

以下是相关的JLS部分:

JLS 15.21.3引用相等运算符 ==!=

如果相等运算符的操作数都是引用类型或者类型,则该操作是对象相等性。

这说明了以下内容:

Integer i = null;
String str = null;
if (i == null) {//Nothing happens
}
if (str == null) {//Nothing happens
}
if (str =="0") {//Nothing happens
}

两个操作数都是引用类型,这就是为什么 == 是引用相等性比较的原因。

这也解释了以下内容:

System.out.println(new Integer(0) == new Integer(0));//"false"
System.out.println("X" =="x".toUpperCase());//"false"

要使 == 为数值相等,至少有一个操作数必须是数字类型:

JLS 15.21.1数字相等运算符 ==!=

equality相等运算符的操作数为为数值类型为,则在操作数上执行二进制数值提升。如果提升类型的操作数是 int 或者 long,那么执行整数相等测试;如果提升的类型是 float or double`,则执行浮点相等测试。

注意二进制数值提升执行值集转换和取消装箱转换。

这说明:

Integer i = null;
if (i == 0) {//NullPointerException
}

下面是 Effective Java 2nd 版的摘录,项目 49:将基元更改为盒装基元:

总之,只要有选择,就使用优先于盒装基元的原语。基本类型更简单更快捷。如果必须使用盒装基元,请小心 !装箱减少了使用盒装基元的详细程度,但不存在危险。当程序比较两个装箱原语与 == 操作符时,它会进行身份比较,这几乎不是你想要的。当程序执行包含装箱和取消装箱原语的混合类型计算时,它将取消装箱,当程序取消装箱时,可以抛出 NullPointerExceptionfinally,当程序框原始值为原始值时,它可以能会造成成本和不必要的对象创作。

除了使用装箱原语,比如 泛型,否则应该严格考虑使用装箱原语的决定。

引用

相关问题

相关问题

原作者:
54 0

你的NPE示例与这里代码相当,因为自动装箱:

if ( i.intValue( ) == 0 )

因此,如果 inull

原作者:
60 0
if (i == 0) {//NullPointerException
. . .
}

我是一个整数,0是一个整数,所以实际上做的就是这样

i.intValue() == 0

这导致了nullPointer因为我是空的。对于字符串,我们没有这个操作,这就是为什么这里没有例外。

原作者:
150 1

Java的制造商可以以定义 == 操作符,直接对不同类型的操作数进行操作,在这种情况下。Integer I; int i;比较 I==i; 可以问问题" I 是否保存对其值为 IInteger的引用"--a问题,即使 I 是空的,也没有困难。然而,Java不直接检查不同类型的操作数是否相等,而是检查语言是否允许将操作数的类型转换为它所转换的其他操作数的类型,即转换为非转换操作。这种行为意味着变量 xyz 有一些类型的组合,可以以有 x==yy==zx!=z [ 。x=16777216f y=16777216 z=16777217] 。它也意味着比较 I==i 被翻译为"转换为 int,如果不引发异常,将它的与 I 比较。"

原作者:
...