当使用“==”比较基本类型和包装类型时,会进行自动装箱还是拆箱操作?

77

以下代码可在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));

它是比较两个Integer对象(通过引用)还是比较两个int变量的值?

请注意,对于某些数字,引用比较会产生正确的结果,因为Integer类在-128127之间维护了一个内部缓存(也请参阅TheLostMind的评论)。这就是为什么我在我的示例中使用了1000并且为什么我明确询问拆箱/装箱而不是比较结果的原因。


11
如果你运行了这段代码并打印输出,那么你肯定可以自己判断。 - Scruffy
9
@Scruffy - 这并不是那么简单。Integer 类维护着一个内部缓存,其范围在 -128 到 127 之间的值。因此,即使你使用 == 比较 Integer i1=100Integer i2=100,你也会得到 true。只有当 i1i2 都不在本地缓存范围内时,你才会得到 false - TheLostMind
2
@TheLostMind,好评论。这就是为什么我选择1000作为我的例子,我会把它加到问题中。 - Thirler
@Thirler - 现在问题看起来更好了 :) - TheLostMind
1
有点相关:https://dev59.com/yHI_5IYBdhLWcg3wHvU5#30415260 - user719662
显示剩余3条评论
3个回答

78
这是在JLS #15.21.1中定义的: 如果相等运算符的操作数都是数字类型,或者其中一个是数字类型而另一个可以转换为数字类型(§5.1.8),则对操作数执行二进制数字提升(§5.6.2)。 而JLS #5.6.2的规定如下: 当运算符对一对必须表示可转换为数字类型的值应用二进制数字提升时,按以下顺序应用以下规则: 如果任何操作数是引用类型,则对其进行取消装箱转换 因此,回答您的问题,Integer将被拆箱为int

46

让我们来做一些例子:

案例-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,则Integer会被拆箱为int,然后进行比较。

如果比较两个Integers,则比较它们的引用。


5
说明
  1. 使用==运算符比较两个原始值时,不会进行自动装箱。

  2. 使用==运算符比较两个对象时,自动装箱起作用。

  3. 当使用混合组合,即包含对象和基本类型,并使用==运算符进行比较时,将在对象上进行自动拆箱并转换为基本类型。

请查看下面的链接,它将帮助您了解关于自动装箱的详细信息,并提供适当的示例。

参考链接:http://javarevisited.blogspot.in/2012/07/auto-boxing-and-unboxing-in-java-be.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接