Kotlin object常量比对Byte时出现NoSuchFieldError异常原因求助
异常产生原因
这个异常是Kotlin编译规则和编译工具链预期不匹配导致的,核心逻辑如下:
- Kotlin
object单例类中未加const修饰的val属性,编译为Java字节码时,不会生成公开的静态字段,只会生成单例实例的私有成员字段+公开的getter方法,你在Kotlin代码中写的myConstants.CheckByte,实际调用的是myConstants.INSTANCE.getCheckByte()getter方法。 - 异常信息里的
isStatic = true是调用侧代码编译时的预期属性,不是myConstants实际字节码里的字段属性:编译调用侧代码时,R8/ProGuard优化、或者跨模块编译缓存不一致的问题,导致编译器错误地认为CheckByte是静态字段,直接生成了读取静态字段的字节码,运行时找不到对应的静态字段就抛出了NoSuchFieldError。
解决方案
最优方案:标记为编译期常量
你的CheckByte是固定值的Byte类型常量,完全符合const val的使用要求,加上const修饰后,Kotlin会直接生成public static final byte CheckByte = 0x13的静态公开字段,完全匹配编译预期,不会再出现该异常:
object myConstants { const val CheckByte: Byte = 0x13 }
其他排查方向
如果加了const还是出现异常,可以按以下步骤排查:
- 清理项目全量重新编译,避免跨模块编译缓存不一致,导致新旧字节码不匹配
- 检查R8/ProGuard混淆规则,是否有误删常量类成员的规则,可临时添加以下规则验证(将包名替换为你实际的包路径):
-keep class 你的包名.myConstants { *; }
内容的提问来源于stack exchange,提问作者Phunction
相关产品推荐
相关产品推荐

