Kotlin伴生对象内列表调用出现NPE的原因解析
伴生对象内列表触发NPE的原因及解决方案解析
为什么会出现NPE?
你之前的认知有个关键偏差:Kotlin伴生对象的初始化时机和Java static成员不一样。
Java里的static成员在类加载时就会完成初始化,只要类被加载,这些成员就处于就绪状态。但Kotlin的伴生对象本质是个叫Companion的嵌套单例类,它的初始化是第一次被主动访问时才触发的,不是外部类加载时同步执行的。
如果你的外部类在初始化过程中(比如init块、其他成员的初始化逻辑)就去访问伴生对象里的firstAndSecond,就会陷入初始化顺序的坑:外部类初始化到一半,触发伴生对象初始化,但伴生对象的成员还没来得及完成初始化就被调用,直接抛出空指针异常。
两种解决方案的原理
1. 把列表移到类外部(顶层声明)
Kotlin的顶层成员会被编译成Java的static字段,初始化时机和Java static成员完全一致——类加载阶段就完成初始化,根本不存在依赖伴生对象的问题,自然不会有NPE。
2. 给伴生对象内的列表加@JvmStatic注解
加了这个注解后,该成员会被直接编译为外部类的static字段,而不是伴生对象类的成员。这样它的初始化时机就和Java static成员同步了,外部类加载时就完成初始化,不再等伴生对象被访问,也就解决了NPE问题。(注意:在线Playground因为缺少对应的编译器插件,没法正确处理这个注解的编译逻辑,所以才会无效)
内容的提问来源于stack exchange,提问作者jazz
相关产品推荐
相关产品推荐

