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

Kotlin中constructor()的用途、作用及是否为主构造函数解答

先直接给结论:你代码里的constructor()不属于主构造函数,是一个无参次构造函数,而且在这段代码里它是完全冗余的,删掉之后代码运行效果没有任何区别。

先明确Kotlin主构造、次构造的核心判定规则和差异
  • 主构造是和类头绑定的,写在类名的后面:标准写法是class 类名 constructor(构造参数) { 类体 }。如果主构造没有可见性修饰符、注解,constructor关键字可以直接省略。你写class Human的时候,Kotlin会默认给你生成一个无参、public的主构造,不需要额外声明。
    主构造不能写业务逻辑,初始化相关的代码需要放在init代码块中,类实例化时主构造是第一入口,init块和类体里的属性初始化会和主构造绑定按顺序执行。
  • 次构造必须写在类体内部,前面必须带constructor关键字。所有次构造都必须直接或者间接委托调用主构造(用this关键字指向本类的其他构造函数即可完成委托),否则会编译报错。次构造可以包含实例化时的额外处理逻辑,通常用来给类提供多种不同参数组合的实例化入口。
回到你贴的代码具体分析

你写的Human类没有在类头声明带参数的主构造,所以编译器默认给它生成了无参主构造。你在类体里写的空参数constructor()是一个次构造,它没有任何自定义逻辑,只是隐式委托了默认的无参主构造,功能和默认主构造完全重合,所以属于无效的冗余代码。
删掉这行之后,你在main里写的val joe = Human()依然可以正常运行,name和id属性会按照你写的初始值正常赋值,humanInfo()的输出结果完全不变。

给你一个次构造的典型使用场景参考,就能明白它的作用:

// 类头声明主构造,要求传入name和id两个参数
class Human(var name: String, var id: String) {
    // 次构造1:只传name,id给默认值,直接委托主构造
    constructor(name: String) : this(name, "000.000.000-00")
    // 次构造2:不传任何参数,给固定默认值,委托给上面的次构造(间接委托主构造)
    constructor() : this("Joe")

    fun humanInfo() = "$name and $id"
}

fun main() {
    val p1 = Human("Alice", "123.456.789-00") // 调用主构造
    val p2 = Human("Bob") // 调用第一个次构造
    val p3 = Human() // 调用第二个次构造,效果和你原来的代码一致
    println(p3.humanInfo()) // 输出 Joe and 000.000.000-00
}

补充一个新手容易踩的坑:如果类已经在类头声明了主构造,类体里所有带constructor的构造方法全是次构造,不委托主构造的话代码根本跑不起来。


内容的提问来源于stack exchange,提问作者edu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 06:15:43