为什么后期初始化var不能与Nullable一起使用?

时间:2019-05-29 05:44:38

标签: android kotlin kotlin-lateinit

为什么我们不能将lateinit与可空变量一起使用?

lateinit var v: String?

lateinit修饰符不允许用于可为空的类型的属性

6 个答案:

答案 0 :(得分:3)

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

如果您希望它是nullable,那么您可以像var b: String? = null一样使用

答案 1 :(得分:3)

如果要创建可为null的变量,则不需要延迟init。医生说

  

通常,声明为具有非null类型的属性必须在构造函数中初始化。   但是,通常这并不方便。例如,可以通过以下方式初始化属性   依赖注入,或在单元测试的设置方法中。在这种情况下,您不能提供非空值   构造函数中的初始值设定项,但您仍想在引用   类内部的属性。

因此,当您打算在构造函数中以外的地方初始化变量并且还希望避免空检查时,应使用延迟初始化。

答案 2 :(得分:2)

如文档中所述,lateinit专门研究非空属性:

  

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

此外,如果您查看此类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
}

答案 3 :(得分:1)

  

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

     

例如,可以通过依赖关系初始化属性   注入或以单元测试的设置方法进行。在这种情况下,您   无法在构造函数中提供非空初始化器,但是您   在引用属性时仍希望避免空检查   在课程正文中。

     

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

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

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

答案 4 :(得分:1)

  

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

因此都是妥协。使用lateinit,您可以确保将变量最终初始化为非null。如果甚至不能保证,可以使用nullable

答案 5 :(得分:0)

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

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