I'm constructing a class and then trying to call a member method of that class as a default value for one of the constructor args.
Why isn't this valid Kotlin?
// unresolved reference: defaultText
class MyThing(val text: String = defaultText()) {
fun defaultText() = "hi"
}
It's possible using two separate constructors in both Java and Kotlin, but then I lose the conciseness of default args.
class MyThing {
private val text: String
constructor(text: String) {
this.text = text
}
constructor() {
this.text = defaultText()
}
private fun defaultText(): String {
return "hi"
}
}
The biggest problem of having a constructor's default parameter expression call a member function of the same instance is that the default arguments are evaluated before the constructor is called.
Given that, such a member function would have to run on a completely un-initialized instance of the class (because even the super constructors will work after that, see this answer about the execution order).
Usually, member functions perform some logic taking the instance state into account, and having a member function run on an empty instance might break some of that logic (e.g. all fields will hold null
s, even the backing fields of Kotlin not-null properties). Overall, even when such calls do not fail at runtime, they are likely introduce subtle bugs, so using a completely uninitialized instance is prohibited.
With regard to the secondary constructor, well, at least it runs after the super constructor initializes some part of the instance, which is thus not completely empty, but it's up to you to make sure you don't use the parts of the class that are not initialized (if you do, you may again encounter a runtime failure or introduce a bug).
I'd rather suggest using a function of a companion object
(those are initialized before the class is first used) for this purpose:
class MyThing(val text: String = defaultText()) {
companion object {
fun defaultText() = "hi"
}
}
Or even a top-level function:
fun defaultText() = "hi"
class MyThing(val text: String = defaultText())
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments