7

为什么我们不能使用lateinit可空变量?

lateinit var v: String?

lateinit可空类型的属性上不允许使用修饰符

4

6 回答 6

11

lateinit仅用于避免将来进行空检查,这就是为什么lateinit在可空类型的属性上不允许使用修饰符的原因。

如果你想要它,nullable那么你可以简单地使用 likevar b: String? = null

于 2019-05-29T05:48:50.540 回答
3

如果你想创建一个可为空类型的变量,那么你不需要 late init 。医生说

通常,声明为非空类型的属性必须在构造函数中初始化。但是,这通常并不方便。例如,可以通过依赖注入来初始化属性,或者在单元测试的 setup 方法中初始化属性。在这种情况下,您不能在构造函数中提供非空初始值设定项,但您仍然希望在引用类主体内的属性时避免空检查。

当您打算在不在构造函数中的某个地方初始化变量并且还希望避免空检查时,可以使用这么晚的 init。

于 2019-05-29T05:52:06.017 回答
2

如文档中所述,lateinit专门研究不可为空的属性:

通常,声明为非空类型的属性必须在构造函数中初始化。但是,这通常并不方便。例如,可以通过依赖注入来初始化属性,或者在单元测试的 setup 方法中初始化属性。在这种情况下,您不能在构造函数中提供非 null初始值设定项,但您仍然希望在引用类主体内的属性时避免 null 检查。

此外,如果您查看此类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
}
于 2019-05-29T06:09:02.773 回答
1

通常,声明为非空类型的属性必须在构造函数中初始化。但是,这通常并不方便。

例如,可以通过依赖注入来初始化属性,或者在单元测试的 setup 方法中初始化属性。在这种情况下,您不能在构造函数中提供非 null 初始值设定项,但您仍然希望在引用类主体内的属性时避免null 检查。

要处理这种情况,您可以使用lateinit 修饰符标记属性。

这就是它不支持null的原因。

因此,如果您将任何var指示为lateinit意味着编译器只是忽略它进行初始化并将其标记为将在不久的将来初始化的非空类型,这就是为什么它不支持可空类型以避免运行时歧义。

于 2019-05-29T05:49:51.223 回答
1

Kotlin 的类型系统旨在消除代码中空引用的危险

所以两者都代表妥协。与lateinit您一起确保变量最终将被初始化为非空。如果你甚至不能保证,你可以使用nullable

于 2019-05-29T05:51:29.413 回答
0

kotlin 的主要功能之一是 Null Safe。

默认情况下,它不允许您创建空值。您已经明确定义
var a: String? = null
,如果您不想为变量初始化任何值,则会出现“lateinit”。使用 lateinit 变量时,您会预先检查它是否已初始化

于 2019-05-29T05:55:36.230 回答