Kotlin中实现类似Java次级构造时,如何避免“Primary constructor call expected”错误?
解决Kotlin中“Primary constructor call expected”错误的方案
错误原因
Kotlin 的构造函数规则明确:如果类定义了主构造函数,所有次级构造函数必须直接或间接调用本类的主构造函数;如果类没有主构造函数,每个次级构造函数则需要直接调用父类的构造函数。你遇到的错误就是因为次级构造未遵循这个规则,没有调用主构造。
修复方案(结合你的需求)
假设你的 Person 父类和 Student 子类的基础代码如下(模拟常见场景):
open class Person(val firstName: String, val lastName: String, val age: Int) // 初始错误的 Student 类 class Student(val degree: String) : Person() { // 若Person无无参构造,此处也会报错 // 第27行的目标构造函数,报错位置 constructor(firstName: String, lastName: String, age: Int, degree: String) { // 未调用主构造,触发错误 } }
方案一:调整主构造,让次级构造调用本类主构造
修改 Student 类,让主构造负责调用父类的构造函数,次级构造通过 this(...) 调用本类主构造:
open class Person(val firstName: String, val lastName: String, val age: Int) class Student( val degree: String, firstName: String, lastName: String, age: Int ) : Person(firstName, lastName, age) { // 主构造调用父类构造 // 第27行的目标构造函数,现在调用本类主构造 constructor(firstName: String, lastName: String, age: Int, degree: String) : this(degree, firstName, lastName, age) }
次级构造通过 this(degree, firstName, lastName, age) 触发本类主构造,而主构造已经正确调用父类构造,完全符合 Kotlin 规则,错误会消失。
方案二:移除主构造,让次级构造直接调用父类构造
如果不需要 Student 类的主构造,可以直接定义多个次级构造,每个构造都通过 super(...) 调用父类对应构造:
open class Person(val firstName: String, val lastName: String, val age: Int) class Student : Person { val degree: String // 原有的构造函数 constructor(degree: String) : super("默认名", "默认姓", 0) { this.degree = degree } // 第27行的目标构造函数 constructor(firstName: String, lastName: String, age: Int, degree: String) : super(firstName, lastName, age) { this.degree = degree } }
这种写法里 Student 没有主构造,每个次级构造直接调用父类构造,同时初始化自身的 degree 属性,同样满足需求且不会报错。
对比Java构造逻辑
Java 中次级构造可以直接调用父类构造或本类其他构造,但 Kotlin 对主构造的存在做了强制约束:只要有主构造,所有次级构造必须先经过主构造的逻辑。这是两者的核心区别,也是你出错的关键。
内容的提问来源于stack exchange,提问作者Coder333
相关产品推荐
相关产品推荐

