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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:22:45