Вызов метода класса по умолчанию arg в конструкторе

Я создаю класс, а затем пытаюсь вызвать метод-член этого класса в качестве значения по умолчанию для одного из аргументов-конструкторов.

Почему это не верно?

// 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 not-null) , В целом, даже когда такие вызовы не прерываются во время выполнения, они, вероятно, вводят тонкие ошибки, поэтому использование полностью неинициализированного экземпляра запрещено.

Что касается вторичного конструктора, то, по крайней мере, он работает после того, как супер-конструктор инициализирует часть экземпляра, которая, таким образом, не является полностью пустой, но вам решать, чтобы вы не использовали части класса, которые не инициализируются (если вы это сделаете, вы можете снова столкнуться с ошибкой во время выполнения или ввести ошибку).

Я бы предпочел использовать функцию companion object (те, которые были инициализированы до того, как класс был впервые использован) для этой цели:

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

Или даже функция верхнего уровня:

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