考虑下述段:

    int i = 99999999;
    byte b = 99;
    short s = 9999;
    Integer ii = Integer.valueOf(9); // should be within cache

    System.out.println(new Integer(i) == i); // "true"
    System.out.println(new Integer(b) == b); // "true"
    System.out.println(new Integer(s) == s); // "true"
    System.out.println(new Integer(ii) == ii); // "false"

这是显而易见的,为什么最后的线 总是 印刷品 "false":我们使用 == 参考身份比较,和一个 new 对象 从来没有== 对一个已经存在的对象。

问题是关于第3行:是那些比较 保证 可以在原始的 int, , Integer 自动装箱?有的情况下,原始将自动装箱代替,并参考的身份比较的执行?(这将所有然后 false!)

有帮助吗?

解决方案

是。 JLS§5.6.2指定规则二进制数值提升。部分:

  

当一个操作者施加的二进制   数值提升到一对   操作数,其中的每一个必须表示一个   值,该值可以转换为一个数字   键入,适用下列规则,在   顺序,使用扩大转换   (§5.1.2)到操作数转换为   必要的:

     

如果任何操作数是一个的   引用类型,取消装箱转换   (§5.1.8)被执行。

二元数值提升适用于几个数字运营商,包括“的数值相等运算==和!=”

JLS§15.21.1(数值相等运算==和=!)规定了:

  

如果相等的操作数   操作者都是数字型,或   一个是数字型的,另一个的   是可兑换(§5.1.8)到数字   类型,二进制数值提升是   对操作数(§5.6.2)进行。

在相反, JLS§15.21.3 (!引用相等运算符==和=)提供:

  

如果相等的操作数   操作者两者都被参考的   键入或null类型,则   操作对象的相等

这符合装箱和拆箱的共识,这就是它只是做时,有一个不匹配。

其他提示

我会第一个解释 恰恰当 == 是一个参考平等、和 恰恰当 这是一个数字上的平等。条件为参照平等是更简单,所以这将可解释第一次。

捷尔思15.21.3的参考平等运营商 ==!=

如果操作数的平等,操作者都要么引用类型或 类型,那么操作的对象的平等。

这说明如下:

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

这两个操作数的 Integer, ,这是参照类型,以及这就是为什么 == 是参照比较平等,以及两个 new 对象将永远不会 == 彼,所以这就是为什么它打印 false.

对于 == 是的数值的平等, 至少一个操作数必须是一个数字型;这是规定如下:

捷尔思15.21.1数平等运营商 ==!=

如果操作数的平等,操作者都是 的数字型,或 一个是 的类型和数字 其他的敞篷车 为数类型的二进制数字,促进执行在操作数。如果推广类型的操作数 intlong, 然后整数的平等进行测试;如果推广类型 float or双`,然后一个浮点平等的执行测试。

注意,二进制数字,促进执行设置的值转换和拆箱的转换。

因此,考虑以下几点:

System.out.println(new Integer(0) == 0); // "true"

这个指纹 true, ,因为:

  • 正确的操作数的 一个数字 int 类型
  • 左边的操作数的 是敞篷车 一个数字型,通过以拆箱 int
  • 因此 == 是的数值的平等,操作

摘要

  • 如果两个操作数的 ==!= 是引用类型,它将始终是一个参考平等操作
    • 不要紧,如果操作数转换为数字类型
  • 如果至少一个操作一个数字型,它将始终是一个数值的平等,操作
    • 自动拆箱上有一个(在最!) 操作数,将进行如有必要

参考文献

相关的问题

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top