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

Kotlin数值装箱测试存疑:为何两次===校验输出不同?

Kotlin Int装箱后===判断结果不一致的疑问

我是Kotlin初学者,无法理解以下测试代码的输出。测试代码如下:

@Test fun testNumberBoxing() {
    val a:Int = 1000
    val boxedA1: Int? = a
    val boxedA2: Int? = a
    println("first check = ${boxedA1 === boxedA2}")
    val b: Int = 2
    val boxedB1: Int? = b
    val boxedB2: Int? = b
    println("second check = ${boxedB1 === boxedB2}")
}

执行结果为:first check = true,second check = false。为何两次输出不同?我的Kotlin版本为1.2.31,依赖org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.31。


嘿,这个问题其实涉及到JVM平台上Kotlin(以及Java)对基本类型装箱的核心优化——整数缓存机制,给你理清楚来龙去脉:

首先得明确:Kotlin里的===对于可空类型(比如Int?)来说,判断的是两个对象的内存引用是否完全相同,也就是它们是不是指向堆里的同一个对象;而==才是判断值是否相等,这点一定要区分开。

接下来看装箱的逻辑:当你把基本类型Int转成可空的Int?时,本质上是在JVM层面把int装箱成了Integer对象。而JVM为了优化性能,会对**-128到127之间的整数进行缓存**:

  • 只要数值在这个区间内,每次装箱都会直接从缓存池里拿现成的对象,所以多次装箱同一个值,得到的是同一个引用,===判断自然返回true;
  • 如果数值超出了这个区间,每次装箱都会新建一个Integer对象,两次装箱的引用肯定不一样,===就会返回false。

不过这里有个小疑问:按照这个逻辑,你的代码正常输出应该是first check = false(1000超出缓存范围,两次装箱是不同对象),second check = true(2在缓存范围内,复用同一个对象),和你给出的结果刚好相反。大概率是你笔误写错了输出,或者测试环境有极端的编译器优化,但核心的原理就是上面说的缓存机制。

补充个小知识点:这个缓存的上限(127)在JVM里可以通过java.lang.Integer.IntegerCache.high这个系统参数调整,但默认情况下都是-128到127,一般不会去改动它。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:28:33