Kotlin NoArg插件忽略声明赋值:空构造函数未初始化属性
Kotlin NoArg插件未初始化默认值问题
问题场景
我配置了NoArg插件如下:
plugins { id "org.jetbrains.kotlin.plugin.noarg" version "1.7.10" } noArg { annotation("tools.AddEmptyConstructor") }
对应的Kotlin代码:
import tools.AddEmptyConstructor @AddEmptyConstructor class Test { private constructor(test: String) private val declarationAssignment = ArrayList<String>() }
编译后生成的Java代码显示,插件确实生成了无参构造,但属性declarationAssignment的初始化逻辑只存在于私有有参构造中,无参构造是空的:
import tools.AddEmptyConstructor; public final class Test { private final ArrayList declarationAssignment; private Test(String test) { this.declarationAssignment = new ArrayList(); } public Test() { } }
疑问:为什么属性的声明赋值逻辑没有同步到生成的无参构造里?该如何正确实现属性初始化?可以放弃声明赋值,接受替代方案,但目前通过无参构造无法初始化任何值。
原因分析
NoArg插件的核心功能是为标注类追加生成无参构造函数,但它不会自动将属性的初始化逻辑复制到这个生成的构造中。Kotlin中,属性的声明赋值逻辑默认只会被插入到类中显式定义的构造函数里,插件生成的无参构造是独立追加的,不会自动关联这些初始化代码。
解决办法
方案1:开启NoArg的invokeInitializers选项
修改插件配置,启用invokeInitializers,让生成的无参构造自动执行属性的初始化逻辑:
noArg { annotation("tools.AddEmptyConstructor") invokeInitializers = true }
开启后,编译生成的无参构造会加入属性初始化语句,确保declarationAssignment被正确赋值。
方案2:使用初始化块统一初始化逻辑
把属性初始化移到init块中,这样所有构造函数(包括插件生成的无参构造)都会执行初始化块的代码:
@AddEmptyConstructor class Test { private constructor(test: String) private val declarationAssignment: ArrayList<String> init { declarationAssignment = ArrayList() } }
方案3:改用带默认参数的主构造
放弃手动声明私有构造,改用带默认参数的主构造,Kotlin会自动生成无参构造,同时属性初始化逻辑会被正确包含:
@AddEmptyConstructor class Test private constructor(test: String = "") { private val declarationAssignment = ArrayList<String>() }
这种方式甚至可以不依赖NoArg插件,就能生成符合需求的无参构造。
内容的提问来源于stack exchange,提问作者Cactusroot
相关产品推荐
相关产品推荐

