java - 在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 中是如何工作的呢?在这种情况下,运算符是否按值进行比较?
解决方案
你所说的“常量值”是一个int
文字,所以它的类型是int
.
如果相等运算符的操作数都是数字类型,或者一个是数字类型而另一个是可转换(第 5.1.8 节)为数字类型,则对操作数执行二进制数字提升。
在您的v1 == 1000
测试中,1000
是数字类型并且v1
可以转换为数字类型,因此执行二进制数字提升。
JLS 5.6.2(二进制数字提升)说:
如果任何操作数是引用类型,则对其进行拆箱转换
因此,Integer
操作数 - v1
- 被拆箱为 anint
并执行两个int
s 的比较。因此比较的结果是true
。
当您比较两种引用类型时v1 == v2
- 不会进行拆箱,仅比较引用,如JLS 15.21.3中所写:
如果相等运算符的操作数既是引用类型又是 null 类型,则该操作是对象相等。
由于1000
太大而无法被缓存Integer
缓存,b1
并且b2
没有引用同一个实例,因此比较的结果是false
.
推荐阅读
- google-chrome - Chrome 扩展程序在扩展程序创建的窗口关闭后关闭
- javascript - 如何在挂载组件之前等待 App.js 代码运行?
- java - Mockito:不在测试函数中抛出错误
- node.js - (Puppeteer) 如何拦截 HTTP 请求并用不同的 body 多次发送?
- azure-aks - 如何从 AKS 上的 nginx 入口监控 HTTP 状态代码?
- powershell - 对以下 powershell 脚本进行等效 wql 查询
- javascript - 默认情况下如何将空的最后一行添加到 Kendo Ui 网格
- rust - 在 Rust 中定义一个采用迭代器而不使用的函数的惯用方法是什么?
- postgresql - 如何在 Postgresql 函数中将变量与表名连接起来?
- elasticsearch - 如何更新ES中在同一字段上查询的所有匹配文档的字段?