欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

Kotlin比较与解释Lazy与Lateinit的用法,

来源: 开发者 投稿于  被查看 36527 次 评论:24

Kotlin比较与解释Lazy与Lateinit的用法,


目录
  • Lateinit
  • Lazy

这里比较与解释 LazyLateinit 的用法。

Lateinit

有时变量的值在其声明的位置不可用。 一个例子是在 Activity 或 Fragment 中使用的 UI widget。 直到 onCreate 或 onCreateView 方法运行,在整个 Activity 中用于引用这些 widget 的变量才能被初始化。 本例中的 submitButton,下面的代码是如果我们不使用 lateinit 的情况:

class HomeFragment: Fragment() {
   // we will provide actual value later
   private var submitButton: Button? = null 
}

我们知道,一个变量必须被初始化。 一个标准的做法就是使这个变量可以为空,并用 null 初始化它。

但是,使用 nullable 类型的问题在于,无论何时在代码中使用 submitButton,都必须检查可空性。 例如:submitButton?.setOnClickListener { .. }。我们必须在 submitButton 后面加上问号。

这个时候,我们就可以使用 lateinit:

class HomeFragment: Fragment() {
    private lateinit var submitButton: Button // will initialize later
}

另外一个例子:

private lateinit var courseName: String
// demo function to get course name using the courseId
fun fetchCourseName(courseId: String) {
    courseName = courseRepository.getCourseName(courseId)
    // this is an example, you can add other suff according to your usecase
}

我们需要非常确定 lateinit 变量在访问它之前会被初始化,否则会报错:

UninitializedPropertyAccessException: lateinit property courseName has not been initialized

如果我们不确定这个 lateinit 变量是否为空,那么可以使用 isInitialized 添加一个检查来检查 lateinit 变量是否已初始化:

if(this::courseName.isInitialized) {
    // access courseName
} else {
    // some default value
}

何时使用 lateinit 初始化

  • 如果变量是可变的(mutable)并且可以在稍后阶段初始化。
  • 必须在使用变量之前对其进行初始化。
  • 使用 var 关键字。

Lazy

某些类的对象初始化非常繁重,并且花费了太多时间,从而导致整个类创建过程的延迟。

例如,假设我们有一个名为 HeavyClass 的类,并且我们需要该 HeavyClass 的对象在其他名为 SomeClass 的类中:

class SomeClass {
    private val heavyObject: HeavyClass = HeavyClass()
}

在这里,我们正在创建一个 heavy object,这将导致 SomeClass 的创建缓慢或延迟。 在某些情况下,我们可能不需要 HeavyClass 对象。 因此,在这种情况下,lazy 关键字起到作用:

class SomeClass {
     private val heavyObject: HeavyClass by lazy {
        HeavyClass()
    }  
}

现在,使用 Lazy 的好处是只有在调用对象时才会创建对象。

使用惰性的另一个好处是,一旦对象被初始化,调用时再次使用同一个对象。

比如:

class SomeClass {
    private val heavyObject: HeavyClass by lazy {
        println("Heavy Object initialised")
        HeavyClass()
    } 
    fun accessObject() {
        println(heavyObject)
    }
}
fun main(args: Array<String>) {
    val someClass = SomeClass()
    println("SomeClass initialised")
    someClass.accessObject()
    someClass.accessObject()
}

打印

SomeClass initialised 
Heavy Object initialised 
HeavyClass@2a84aee7 
HeavyClass@2a84aee7

何时使用 Lazy 初始化

  • 除非你调用它,否则变量不会被初始化。
  • 初始化变量一次; 然后在整个代码中使用相同的值。
  • 在 val 属性的情况下使用,即作为同一对象的只读属性将在整个程序中共享

到此这篇关于Kotlin比较与解释Lazy与Lateinit的用法的文章就介绍到这了,更多相关Kotlin Lazy Lateinit内容请搜索3672js教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持3672js教程!

您可能感兴趣的文章:
  • Kotlin对象的懒加载方式by lazy 与 lateinit 异同详解
  • 聊聊Kotlin 中 lateinit 和 lazy 的原理区别
  • Kotlin lateinit与by lazy案例详解

用户评论