原文链接。
Kotlin提供了许多很棒的特性。我们可以利用这些功能,快速构建高质量的应用程序。在所有这些特性中,lateinit
和 lazy
是重要的初始化属性。有必要知道何时使用 lateinit
以及何时使用 lazy
初始化。
‘lateinit’
有时变量的值在其声明位置并不可用。对于 Android 开发者来说,一个明显的例子是在 Activity
或 Fragment
中使用的 UI 小部件。直到 onCreate
或 onCreateView
方法运行,整个 activity 中用于引用小部件的变量才能初始化。本例中的 submitButton
,例如:
示例1.1无lateint的对象初始化
class HomeFragment: Fragment() {
// 我们稍后将提供实际的值
private var submitButton: Button? = null
}
必须初始化变量。由于我们还不能知道值,一种标准的技术是使变量可以为空并用 null
初始化它。
然而,使用可空类型的问题是,无论何时在代码中使用 submitButton
,都必须检查可空性。例如:submitButton?.setOnClickListener { .. }
。像这样的几个变量,你会得到很多恼人的问号!如果您习惯了Java及其简单的点表示法,这看起来会特别混乱。
您可能会问,为什么当你确信在任何东西尝试访问它之前将对其进行初始化的时候,Kotlin 还要阻止我使用非空类型声明 submitButton
?
这是可能的。您可以使用 lateinit
修饰符来完成这项工作,如下代码所示:
示例1.2使用 lateint 初始化对象
class HomeFragment: Fragment() {
private lateinit var submitButton: Button // 将在稍后初始化
}
由于变量被声明为 lateinit
,Kotlin 将允许您在不为其赋值的情况下声明它。变量必须是可变的,即 var
,因为根据定义,您稍后将为其赋值。大问题解决了,对吧?
当你使用 lateinit
时,你会告诉编译器,“我现在没有值给你,但我保证以后会给你值。”如果出了什么问题,那是你的错。”
通过使用 lateinit
修饰符,可以为变量禁用 Kotlin 的 null 安全性。如果忘记初始化变量或在初始化之前尝试对其调用某些方法,则会得到 UninitializedPropertyAccessException
,这与在 Java 中获得 NullPointerException
基本相同。
何时使用 lateinit
初始化
- 如果变量是可变的,并且可以在稍后阶段初始化。
- 你能确定在使用变量之前,一定会初始化它。
- 使用
var
关键字。
Lazy 属性
在软件工程中,延迟创建和初始化对象直到实际需要它为止,是一种常见的模式。这种模式被称为延迟初始化,在 Android 上尤其常见,因为在 app 启动期间分配大量对象可能会导致更长的启动时间。下面是 Java 中延迟初始化的典型例子。
示例2.1 Java 延迟初始化
class MyClass {
private HeavyObject heavy; public HeavyObject getHeavy() {
if (heavy == null) {
heavy = new HeavyObject();
}
return heavy;
}
}
仅当通过调用(例如,大概这样, myClass.getHeavy()
)首次请求其值时,才使用类 HeavyObject
的新实例初始化字段 heavy
(可能创建起来需要很大的代价)。对 getHeavy()
的后续调用将返回缓存的实例。
在Kotlin中,延迟初始化是语言的一部分。通过使用 lazy 指令并提供初始化块,lazy 实例化的其余部分是隐式的,如下所示:
示例2.2 Kotlin lazy(延迟) 初始化
class MyClass {
val heavy by lazy { // 初始化块儿
HeavyObject()
}
}
请注意,示例2.1中的代码不是线程安全的。同时调用 MyClass
的 getHeavy()
方法的多个线程,可能会得到不同的 Heavyweight
实例。
默认情况下,示例2.2中的代码是线程安全的。对 MyClass::getHeavy()
的调用将是 synchronized 的 ,以便一次只有一个线程在初始化块中。
可以使用 LazyThreadSafetyMode
管理对延迟初始化块的并发访问的细粒度控制。
在运行时(runtime)调用之前,Kotlin lazy 值是不会被初始化的。当第一次引用属性 heavy
时,将运行初始化块。
何时使用 Lazy(延迟)
初始化
- 只有你调用它的时候,变量才会被初始化。
- 初始化变量一次;然后在整个代码中使用相同的值。
- 在
val
属性的情况下使用,即,作为同一对象的只读属性将在整个程序中共享。
就这样结束了,伙计们。 请继续关注接下来的文章。 如果有任何问题或建议,请随时在领英上联系我。 谢谢!!!
不断探索,不断学习,不断成长