Как показано D3xter у вас есть возможность установить его в конструкторе. У вас также есть другие варианты. Вот они все ...
Создать свойство внутри конструктора (в соответствии с @ D3xter), это самый распространенный случай для простых свойств инициализируются непосредственно первичным конструктором:
class TestClass(private val context: Context) {
fun doSomeVoodoo() {
val text : String = context.getString()
}
}
Вы можете объявить свойство val
, а не инициализировать его, если все возможные конструкторы действительно инициализируют его (согласно вашему второму примеру в заданном вопросе). Это нормально, когда у вас есть более чем один конструктор, который может инициализировать значение по-разному:
public class TestClass {
private val context: Context
public constructor(context : Context) {
this.context = context
}
// alternative constructor
public constructor(pre: PreContext) {
this.context = pre.readContext()
}
public fun doSomeVoodoo() {
val text : String = context.getString()
}
}
Вы можете передать в параметрах конструктора, которые не являются декларацией собственности, а затем использовать те, в инициализациях собственности. Это часто встречается, когда у вас есть более сложная инициализация или нужно использовать делегированные свойства:
class TestClass(context: PreContext) {
private val context : Context by lazy { context.readContext() }
private val other: List<Items> = run {
context.items.map { it.tag }.filterNotNull()
}
private val simpleThing = context.getSimple()
fun doSomeVoodoo() {
val text : String = context.getString()
}
}
Использование lateinit
modifier, когда вы не можете инициализировать значение в процессе строительства, но вы уверены, что это будет сделано до первого доступа для чтения. Это является общим, когда инъекция зависимости, IoC контейнер, или что-то создает пустую версию своего класса, а затем инициализирует его сразу:
class TestClass() {
private lateinit var context : Context // set by something else after construction
fun doSomeVoodoo() {
val text : String = context.getString()
}
}
Для lateinit
собственность должна в настоящее время быть var
и не работает с примитивным типы.
Вы также можете объявить объект var
, а не инициализировать его, если используете делегат, предназначенный для этой цели, такой как Delegates.notNull()
.Это похоже на lateinit
и часто, когда вы хотите var
, который не имеет начального состояния, но устанавливается позже, после строительства в неизвестном момент времени:
public class TestClass() {
private var context: Context by Delegates.notNull()
public fun doSomeVoodoo() {
// if context is not set before this is called, an exception is thrown
val text : String = context.getString()
}
}
Второй пример работы с Котлин 0.12.213. Какую версию Kotlin вы используете? – D3xter
Работает. Я уже использовал 0.12.613. Но я думаю, что я делал что-то неправильно. Сожалею! – Christopher
Есть больше доступных случаев, я добавил ответ для полного покрытия. –