Почему мы не можем использовать lateinit
с переменными, допускающими значение NULL?
lateinit var v: String?
lateinit
модификатор не разрешен для свойств типов, допускающих значение NULL
Послушай, я знаю, что инициализирую его некоторым значением, но это будет значение, допускающее значение NULL, при присвоении этого значения переменной, которую мы объявили, появится предупреждение
lateinit
предназначен только для того, чтобы избежать проверок на null в будущем, поэтому модификатор lateinit
не разрешен для свойств типов, допускающих значение null.
Если вы хотите, чтобы это было nullable
, вы можете просто использовать лайк var b: String? = null
Normally, properties declared as having a non-null type must be initialized in the constructor. However, fairly often this is not convenient.
For example, properties can be initialized through dependency injection, or in the setup method of a unit test. In this case, you cannot supply a non-null initializer in the constructor, but you still want to avoid null checks when referencing the property inside the body of a class.
To handle this case, you can mark the property with the
lateinit
modifier.
Вот почему он не поддерживает нулевой.
Итак, если вы укажете какой-либо вар как поздно, это означает, что компилятор просто игнорирует его для инициализации и помечает как ненулевой тип, который будет инициализирован в ближайшем будущем, и поэтому он не поддерживает тип, допускающий значение NULL, чтобы избежать неоднозначности во время выполнения.
Цитируйте документацию (и другие источники ответов), а не просто копируйте ее.
Kotlin's type system is aimed at eliminating the danger of null references from code
так что оба представляют собой компромиссы. С lateinit
вы гарантируете, что переменная в конечном итоге будет инициализирована ненулевой. Если вы даже этого не можете гарантировать, вы можете использовать обнуляемый.
Если вы хотите создать переменную типа nullable, то вам не нужна поздняя инициализация. Док говорит
Normally, properties declared as having a non-null type must be initialized in the constructor. However, fairly often this is not convenient. For example, properties can be initialized through dependency injection, or in the setup method of a unit test. In this case, you cannot supply a nonnull initializer in the constructor, but you still want to avoid null checks when referencing the property inside the body of a class.
Таким образом, поздняя инициализация предназначена для использования, когда вы собираетесь инициализировать переменную где-то не в конструкторе, а также хотите избежать проверок на нуль.
Одна из главных фич kotlin — Null Safe.
По умолчанию это не позволит вам создать нулевое значение. Вы явно определилиvar a: String? = null
, Если вы не хотите инициализировать какое-либо значение переменной, приходит «lateinit». При использовании переменной lateinit вы предварительно проверяете, инициализирована она или нет.
Как указано в документации, lateinit
специализируется на ненулевых свойствах:
Normally, properties declared as having a non-null type must be initialized in the constructor. However, fairly often this is not convenient. For example, properties can be initialized through dependency injection, or in the setup method of a unit test. In this case, you cannot supply a non-null initializer in the constructor, but you still want to avoid null checks when referencing the property inside the body of a class.
Кроме того, если вы посмотрите на байтовый код такого свойства lateinit
, вы увидите, что компилятор добавляет блок кода, чтобы гарантировать, что это свойство было инициализировано при доступе. Для свойств lateinit
null
указывает на начальное, но недопустимое состояние свойств.
class WithLateInit {
lateinit var something : String
}
становится
public final class WithLateInit {
@NotNull
public String something;
@NotNull
public final String getSomething() {
String var10000 = this.something;
if (var10000 == null) { // <- here you can see the lateinit check
Intrinsics.throwUninitializedPropertyAccessException("something");
}
return var10000;
}
//setter
}
Я не знаю подробностей, но если подумать, если бы вы позволили это, зачем бы вы это сделали
lateinit
? Просто инициализируйте его какnull
.