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

Kotlin中可空装箱Int类型行为差异的原因问询

Kotlin可空变量装箱行为差异解释

核心差异:装箱触发时机不同

两个示例的本质区别是装箱操作发生的阶段和次数不一样,===是引用相等比较,只有指向同一个堆对象才会返回true,我们分别拆解两段代码的执行逻辑:


第一段代码(a、b为非空Int类型)的执行逻辑

代码如下:

val a: Int = 100
val boxedA: Int? = a
val anotherBoxedA: Int? = a

val b: Int = 10000
val boxedB: Int? = b
val anotherBoxedB: Int? = b

println(boxedA === anotherBoxedA) // true
println(boxedB === anotherBoxedB) // false
  • Kotlin中非空基础类型(如Int) 会默认映射为JVM的原始类型(对应int),不存在装箱,存储在栈上,没有堆对象引用。
  • 每次把原始类型的Int赋值给可空类型Int?时,都会触发一次装箱操作,调用JDK的Integer.valueOf()方法生成堆上的Integer对象。
    • Integer.valueOf()对-128~127范围的数值做了缓存,相同值会返回同一个缓存对象,所以两次装箱100得到的是同一个对象,引用比较为true。
    • 10000超出缓存范围,每次调用Integer.valueOf()都会生成新的Integer对象,两次装箱得到的是不同对象,引用比较为false。

第二段代码(a、b为可空Int?类型)的执行逻辑

代码如下:

val a: Int? = 100
val boxedA: Int? = a
val anotherBoxedA: Int? = a

val b: Int? = 10000
val boxedB: Int? = b
val anotherBoxedB: Int? = b

println(boxedA === anotherBoxedA) // true
println(boxedB === anotherBoxedB) // true
  • Kotlin中可空基础类型(如Int?) 无法映射为JVM原始类型,只要声明就会自动装箱为堆上的Integer对象。
    • 声明val a: Int? = 100的时候,已经完成了唯一一次装箱,生成了一个Integer对象,a持有的是这个对象的引用。
    • 后续把a赋值给boxedA和anotherBoxedA,只是把同一个对象的引用复制了两次,没有触发新的装箱操作,全程只有一个Integer对象。
  • 不管数值是不是在-128~127的缓存范围,两个引用都指向同一个对象,所以===比较结果都是true。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 21:18:04