Kotlin中数值装箱后引用相等性(===)差异原因探究
为什么Kotlin中
===对<128的装箱数值返回true,对>=128返回false? 这个问题的核心其实是JVM平台的整数对象缓存机制——Kotlin在JVM上运行时,会复用Java的这个性能优化特性,咱们一步步拆解:
1. 先明确===在Kotlin中的行为差异
对于运行时表示为原始类型的值(例如Int),=相等检查等价于检查
官方文档的这句话没错,但要注意前提是「原始类型」。当你把Int赋值给Int?类型的变量时,Kotlin会自动把原始类型装箱成Integer对象(JVM层面),这时候===就不再是值比较,而是对象引用的相等性检查——它判断的是两个变量是否指向内存中的同一个对象。
2. JVM的整数缓存规则
为了避免频繁创建小范围整数的对象(这类数值在代码中使用频率极高),JVM会提前缓存-128到127之间的Integer对象。当你对这个范围内的int值进行装箱时,会直接返回缓存池里的已有对象;而超出这个范围的数值,每次装箱都会创建一个全新的Integer对象。
3. 对应你的代码示例验证
示例1:数值127(在缓存范围内)
val a = 127 val boxedA: Int? = a val anotherBoxedA: Int? = a print(boxedA === anotherBoxedA) // 输出true
这里boxedA和anotherBoxedA指向的是缓存池中的同一个Integer对象,所以引用相等,===返回true。
示例2:数值128(超出缓存范围)
val a = 128 val boxedA: Int? = a val anotherBoxedA: Int? = a print(boxedA === anotherBoxedA) // 输出false
这时候每次装箱都会新建一个Integer对象,boxedA和anotherBoxedA指向内存中不同的对象,所以引用不相等,===返回false。
示例3:原始类型的===
val a: Int = 10000 print(a === a) // 输出true
这里a是原始类型Int,===等价于值比较,自然返回true,和缓存机制无关。
补充说明
这个缓存范围其实可以通过JVM参数-XX:AutoBoxCacheMax=<size>调整,但默认的-128到127是Java语言规范规定的标准行为,Kotlin作为JVM语言自然继承了这个特性。
内容的提问来源于stack exchange,提问作者Pyts Mike
相关产品推荐
相关产品推荐

