You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中Integer与Double拆箱赋值的引用行为差异问题咨询

问题原因分析

核心是Java对不同包装类的自动装箱逻辑和缓存机制存在差异,具体拆解如下:

1. 先明确代码里的隐式操作

你调用的setIntVal(Integer intVal)、setDoubleVal(Double doubleVal)入参是包装类,而你传入的是inst1.getIntVal().intValue()(返回基础类型int)、inst1.getDoubleVal().doubleValue()(返回基础类型double),这一步Java会自动执行自动装箱,编译器会隐式把代码转换成:

inst2.setDoubleVal(Double.valueOf(inst1.getDoubleVal().doubleValue()));
inst2.setIntVal(Integer.valueOf(inst1.getIntVal().intValue()));

你观察到的对象地址差异,本质是Double.valueOf()和Integer.valueOf()的实现逻辑不同。

2. Integer的缓存规则

Java对Integer类型做了内置缓存优化:

  • 默认会缓存-128 ~ 127区间内的所有Integer实例
  • 只要调用Integer.valueOf()传入的int值在这个区间内,会直接返回缓存中已经创建好的对象,不会生成新实例
    你代码里用到的10正好落在缓存区间内,所以两次装箱拿到的是同一个缓存对象,地址完全相同。
    补充验证:如果你把intVal的值换成128(超出缓存区间),两次装箱得到的也会是不同的Integer对象,和Double的表现一致

3. Double没有固定缓存的原因

Double是浮点数类型,即便是有限区间内,可取值的数量也是近乎无穷的,没有办法像Integer那样做固定范围的预缓存,所以Double.valueOf()每次调用都会生成一个全新的Double实例,哪怕两次传入的double值完全相同,返回的对象地址也不一样。

调试器里显示的@xxx就是对象在JVM里的虚拟地址标识,地址相同就是同一个对象,地址不同就是不同对象,和你观察到的现象完全匹配。

内容的提问来源于stack exchange,提问作者Wiatrak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 05:36:01