首页 > 解决方案 > 在Java中,比较一个对象和一个常量值时“==”是Box还是Unbox?

问题描述

在比较 Integer 对象和常量值时,Java 是否将值装箱或取消装箱 Integer 对象?

根据我所阅读的内容,“==”是一个引用比较,因此假设 Java 封装常量来执行对象之间的引用比较是合乎逻辑的。然而,下面的测试代码似乎给出了矛盾的结果。

Integer v1 = 1000;
Integer v2 = 1000;
boolean b1 = v1 == 1000; //True.
boolean b2 = v1 == v2; //False. Proof that 1000 boxes to new object and is not fetched from cache.

那么对象与常量值比较==在 Java 中是如何工作的呢?在这种情况下,运算符是否按值进行比较?

标签: javareferenceequalscomparison-operators

解决方案


你所说的“常量值”是一个int文字,所以它的类型是int.

JLS 15.21.1说:

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

在您的v1 == 1000测试中,1000是数字类型并且v1可以转换为数字类型,因此执行二进制数字提升。

JLS 5.6.2(二进制数字提升)说:

如果任何操作数是引用类型,则对其进行拆箱转换

因此,Integer操作数 - v1- 被拆箱为 anint并执行两个ints 的比较。因此比较的结果是true

当您比较两种引用类型时v1 == v2- 不会进行拆箱,仅比较引用,如JLS 15.21.3中所写:

如果相等运算符的操作数既是引用类型又是 null 类型,则该操作是对象相等。

由于1000太大而无法被缓存Integer缓存,b1并且b2没有引用同一个实例,因此比较的结果是false.


推荐阅读