在Java中,当比较对象和常量值时,“==”是装箱还是拆箱?

Amr*_*mar 5 java reference equals comparison-operators

当比较 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.
Run Code Online (Sandbox Code Playgroud)

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

Era*_*ran 4

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

\n\n

JLS 15.21.1说:

\n\n
\n

如果等式运算符的操作数均为数字类型,或者一个为数字类型,另一个可转换(\xc2\xa75.1.8)为数字类型,则对操作数执行二进制数字提升。

\n
\n\n

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

\n\n

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

\n\n
\n

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

\n
\n\n

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

\n\n

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

\n\n
\n

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

\n
\n\n

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

\n