在构造函数中调用类的方法作为默认参数

我正在构造一个类,然后试图调用该类的成员方法作为其中一个构造函数参数的默认值。

为什么不是有效的Kotlin?

// unresolved reference: defaultText class MyThing(val text: String = defaultText()) { fun defaultText() = "hi" } 

在Java和Kotlin中使用两个独立的构造函数是可能的,但是我失去了默认参数的简洁性。

 class MyThing { private val text: String constructor(text: String) { this.text = text } constructor() { this.text = defaultText() } private fun defaultText(): String { return "hi" } } 

使构造函数的默认参数表达式调用同一个实例的成员函数的最大问题是构造函数被调用之前计算默认参数。

鉴于此,这样的成员函数将不得不在类的完全未初始化的实例上运行(因为即使超级构造函数也会在此之后工作, 请参阅关于执行顺序的答案 )。

通常情况下,成员函数执行一些考虑实例状态的逻辑,并且在一个空实例上运行一个成员函数可能会破坏一些逻辑(例如,所有字段都将保留为null ,甚至是Kotlin非空属性的后备字段) 。 总的来说,即使这样的调用在运行时没有失败,它们可能会引入微妙的错误,因此禁止使用完全未初始化的实例。

关于次级构造函数,至少在超级构造函数初始化实例的一部分之后运行,因此不是完全空的,但是要确保不要使用类的部分没有初始化(如果你这样做,你可能会遇到运行时失败或引入错误)。

我宁愿建议使用companion object的函数(在类被首次使用之前初始化)来实现这个目的:

 class MyThing(val text: String = defaultText()) { companion object { fun defaultText() = "hi" } } 

甚至是一个顶级的功能:

 fun defaultText() = "hi" class MyThing(val text: String = defaultText())