将 == 用于基元和装箱值时,是自动装箱已完成,还是取消装箱完成

2022-08-31 13:39:44

以下代码进行编译(使用 Java 8):

Integer i1 = 1000;
int i2 = 1000;
boolean compared = (i1 == i2);

但是它有什么作用呢?

开箱 :i1

boolean compared = (i1.intvalue() == i2);

或包装盒 :i2

boolean compared = (i1 == new Integer(i2));

那么,它是按值比较两个对象(通过引用)还是两个变量呢?Integerint

请注意,对于某些数字,引用比较将产生正确的结果,因为 Integer 类维护了介于 到 之间的值的内部缓存(另请参阅 TheLostMind 的注释)。这就是为什么我在示例中使用的原因,以及为什么我专门询问拆箱/装箱而不是比较结果的原因。-1281271000


答案 1

它在 JLS #15.21.1 中定义:

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

JLS #5.6.2

当运算符将二进制数字提升应用于一对操作数(每个操作数必须表示可转换为数字类型的值)时,以下规则按顺序适用:

  • 如果任何操作数是引用类型,则进行拆箱转换 [...]

因此,为了回答您的问题,已取消装箱到.Integerint


答案 2

让我们做一些例子:

案例 -1 :

       public static void main(String[] args) {
            Integer i1 = 1000;
            int i2 = 1000;
            boolean compared = (i1 == i2);
            System.out.println(compared);
        }

字节码 :

....
        16: if_icmpne     23 // comparing 2 integers
....

案例 -2 :

public static void main(String[] args) {
    Integer i1 = 1000;
    Integer i2 = 1000;
    //int i2 = 1000;
    boolean compared = (i1 == i2);
    System.out.println(compared);
}

字节码 :

...
     16: if_acmpne     23 // comparing references
....

因此,在比较和的情况下,被拆箱到一个,然后进行比较发生。Integerint==Integerint

在比较2的情况下,比较2的参考。IntegersIntegers


推荐