升级Kotlin1.5.0后inline链式调用报NPE但拆分变量写法正常?
问题原因分析
核心诱因
该异常本质是Gson反序列化逻辑和Kotlin空安全机制不兼容导致的:Gson可以通过反射绕过Kotlin的编译期非空校验,给声明为非空类型的实体类属性直接注入null值,破坏Kotlin的空安全约定。
两种写法的运行差异原因
- 单行链式调用:Kotlin 1.5+ 编译器针对链式调用做了冗余安全调用优化,如果你的实体类中某一步访问的属性被声明为非空类型,编译器会判定该属性永远不可能为null,直接将你写的
?.安全调用优化为普通调用。当这个属性实际已经被Gson注入为null时,访问操作会触发Kotlin的隐性非空检查,直接抛出空指针异常。 - 拆分变量写法:每一步的执行结果都被显式赋值给可空类型变量,此时编译器不会优化安全调用逻辑,每一步都会执行显式空判断,只要某一步返回null,后续的安全调用就不会执行,最终走到
?:分支返回空集合,不会触发异常。
修复建议
- 所有用于Gson反序列化的Kotlin实体类属性统一声明为可空类型,避免空安全被破坏后触发隐性NPE
- 接入Gson官方Kotlin支持适配器,反序列化时对非空属性做严格校验,避免null被非法注入
- 替换为Kotlin原生序列化库kotlinx.serialization,从根源避免反射注入导致的空安全问题
内容的提问来源于stack exchange,提问作者Daniel Churm
相关产品推荐
相关产品推荐

