在Java中是否保证新整数(i)==i?

在Java中是否保证新整数(i)==i?,java,comparison,autoboxing,implicit-conversion,Java,Comparison,Autoboxing,Implicit Conversion,考虑以下代码段: 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" Syst

考虑以下代码段:

    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”:我们正在使用
=
引用身份比较,一个
新的
对象将永远不会
=
到一个已经存在的对象

问题是关于前3行:这些比较是否保证
int
原语上,并且
整数
自动取消绑定?是否存在原语自动装箱并执行引用标识比较的情况?(然后都是
false
!)

是。指定二进制数字升级的规则。部分:

当运算符应用二进制 数字升级到一对 操作数,每个操作数必须表示 可转换为数值的值 在中,以下规则适用 顺序,使用加宽转换 (§5.1.2)将操作数转换为 必要的:

如果任何操作数为 引用类型,取消装箱转换 (§5.1.8)的规定

二进制数字提升适用于多个数字运算符,包括“数字相等运算符==和!=”

(数字相等运算符==和!=)指定:

如果相等的操作数 运算符都是数字类型,或 一个是数字类型,另一个是数字类型 可转换(§5.1.8)为数字 类型,二进制数字升级为 对操作数执行(§5.6.2)

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

如果相等的操作数 运算符都是其中一个引用 类型或空类型,然后 操作是对象相等

这符合装箱和拆箱的一般理解,即只有在不匹配的情况下才执行。

我将首先精确解释
==
何时为参考等式,何时为数字等式。引用相等的条件更简单,因此将首先对其进行解释

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

这说明了以下几点:

System.out.println(new Integer(0) == new Integer(0)); // "false"
System.out.println(new Integer(0) == 0); // "true"
两个操作数都是
整数
,都是引用类型,这就是
=
是引用相等比较的原因,两个
新的
对象永远不会彼此
=
,所以它会打印

若要使
==
成为数字相等,至少一个操作数必须是数字类型;具体规定如下:

如果相等运算符的操作数都是数值类型的,或者一个是数值类型的,另一个是可转换为数值类型的
,则对操作数执行二进制数值提升。如果提升后的操作数类型为
int
long
,则执行整数相等测试;如果提升的类型是
float或
double`,则执行浮点相等测试

请注意,二进制数字升级执行值集转换和取消装箱转换

因此,考虑以下内容:

System.out.println(new Integer(0) == new Integer(0)); // "false"
System.out.println(new Integer(0) == 0); // "true"
这将打印
true
,因为:

  • 右操作数是数值
    int
    类型
  • 左操作数可以通过取消装箱到
    int
  • 因此,
    ==
    是一个数值相等操作

总结
  • 如果
    ==
    的两个操作数同时存在=是引用类型,它将始终是引用相等操作
    
    • 操作数是否可转换为数字类型并不重要
  • 如果至少有一个操作数是数值类型,则它将始终是数值相等操作
    • 如有必要,将对一个(最多!)操作数执行自动取消装箱
工具书类
    • “数字类型是整数类型和浮点类型。”
相关问题

您的问题中是否有输入错误-所有4个比较都使用==,这将返回false,因为您正在比较的左侧创建一个新实例。好的,我明白了。好问题!这听起来像是
新整数(0)==新整数(0)
(即
false
)应该是
true
,因为“任何操作数都是引用类型,将执行取消装箱转换”。你能进一步澄清这一点吗?它适用于算术运算符,在新整数(0)==新整数(0)中,“==”是引用相等运算符,而不是算术运算符。@polygene,我进一步解释了为什么你的注释示例使用对象相等。