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

Kotlin值比较异常问题:==返回false但===返回true的原因求解

问题原因分析

这个现象是Kotlin老版本编译器的类型推断逻辑、JVM数字类型装箱规则、Java包装类equals实现三者共同作用的结果,具体拆解如下:

1. 为什么println(m!!.a == NUM)输出true

  • !!操作符会强制将可空类型Foo?转为非空类型,如果m为null会直接抛出空指针异常,因此m!!.a的类型是确定的非空基础类型Byte,和NUM的类型完全一致。
  • 此处==执行基础类型的数值比较,两个值都是1,结果自然为true。

2. 为什么println(m?.a === NUM)输出true

  • ===是Kotlin的引用相等比较符,只有两个操作数指向JVM堆中的同一个对象时才会返回true。
  • m?.a的返回类型是可空Byte?,会被自动装箱为java.lang.Byte包装对象;右操作数NUM是基础类型,进行引用比较时也会触发自动装箱。
  • JVM默认对Byte类型的包装对象提供了缓存,数值范围在-128~127之间的Byte包装对象会复用缓存中的同一个实例,因此两者是同一个对象,引用比较结果为true。

3. 为什么println(m?.a == NUM)输出false

  • 这里==是对象值比较,本质是调用左操作数的equals方法。
  • 老版本Kotlin编译器在这里存在类型推断缺陷:右操作数NUM是基础类型Byte,和左操作数Byte?比较时,会被错误地先提升为Int类型,再装箱为java.lang.Integer对象。
  • 查看java.lang.Byte的equals方法实现,会先判断传入的参数类型是否为Byte,如果不是直接返回false,所以1的Byte对象和1的Integer对象比较结果就是false。

补充说明:这个问题在Kotlin 1.4及以上版本中已经被修复,相同代码在新版本中运行m?.a == NUM也会返回true。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 01:09:02