Kotlin中的延迟属性(lazy properties)

属于Kotlin中的委托属性这一章中的标准委托

延迟属性Lazy

lazy() 是接受一个lambda 并返回一个 Lazy <T> 实例的函数,返回的实例可以作为实现延迟属性的委托。也就是说: 第一次调用get() 会执行已传递给 lazy() 的 lambda 表达式并记录结果, 后续调用get() 只是返回记录的结果。

这里需要注意的是 调用的是 get()方法,和set没啥关系

val lazyValue: String by lazy {
    println("computed!")
    "Hello"
}

fun main(args: Array<String>) {
    println(lazyValue)
    println(lazyValue)
}

输出结果为

computed!
Hello
Hello

同步锁模式

防止对个线程同时初始化

默认情况下,对于 lazy 属性的求值是同步锁的(synchronized):该值只在一个线程中计算,并且所有线程会看到相同的值。如果初始化委托的同步锁不是必需的,这样多个线程可以同时执行,那么将 LazyThreadSafetyMode.PUBLICATION 作为参数传递给 lazy() 函数。 而如果你确定初始化将总是发生在单个线程,那么你可以使用 LazyThreadSafetyMode.NONE模式, 它不会有任何线程安全的保证和相关的开销。

延迟属性Lazy 与 lateinit 区别

以下是lateinit var和by lazy { ... }委托属性之间的显著差异:

  • lazy { ... }代表只能用于val属性,而lateinit只能用于var,因为它不能编译到final字段,因此不能保证不变性;
  • lateinit var具有存储值的后备字段(backing field),而by lazy { ... }创建一个委托对象,其中存储一次计算的值,将对代理实例的引用存储在类对象中,并为与委托实例一起使用的属性生成getter。
  • 除了val之外,lateinit不能用于可空属性和Java原语类型(这是因为null用于未初始化的值);所以如果你需要在类中存在的支持字段,请使用lateinit; lateinit var可以从对象被看到的任何地方被初始化。从一个框架代码的内部,多个初始化方案是可能的单一类的不同对象。 by lazy { ... }反过来又定义了属性的唯一初始化器,只能通过覆盖子类中的属性进行更改。如果您希望以预先未知的方式从外部初始化属性,请使用lateinit。
  • 另外,还有一个方法没有提到Delegates.notNull(),它适用于non-null属性的延迟初始化,包括Java原始类型的属性。

延迟属性Lazy 与 lateinit 使用总结

lateinit用于外部初始化:当需要外部资料通过调用方法初始化您的值时。 例如通过调用:

private lateinit var value: MyClass

fun init(externalProperties: Any) {
   value = somethingThatDependsOn(externalProperties)
}

lazy当它只使用对象内部的依赖关系时。 嗯。静态变量的初始化挺适合这种方式的。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏noteless

-1-6 java 异常简单介绍 java异常 异常体系 Throwable 分类 throws和throw 异常处理 自定义异常

异常由来:问题也是现实生活中一个具体事务,也可以通过java 的类的形式进行描述,并封装成对象。

12030
来自专栏C/C++基础

CC++变参函数

C语言中,有时需要变参函数来完成特殊的功能,比如C标准库函数printf()和scanf()。C中提供了省略符“…”能够帮主programmer完成变参函数的书...

9810
来自专栏python学习指南

Python的itertools模块

本章将介绍Python自建模块itertools,更多内容请参考:Python参考指南 python的自建模块itertools提供了非常有用的用于操作迭代对...

35960
来自专栏大闲人柴毛毛

稳扎稳打JavaScript(一)——作用域链内存模型

几个概念 在开始之前,先了解几个概念。 1.1. 作用域 作用域是指当前正在执行的代码能够访问到变量的范围; 每个函数都有各自的作用域,存储函数所有的局部变量...

49080
来自专栏蜕变

Python 数据类型

Python主要数据类型包括list(列表)、tuple(元组)、dict(字典)和set(集合)等对象,下面逐一介绍这些Python数据类型。

9600
来自专栏淡定的博客

python入门基础语法总结

11230
来自专栏大前端_Web

js浮点数加减乘除

版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://blog.csdn.net/wkyseo/articl...

20230
来自专栏老司机的技术博客

人人都能学会的python编程教程10:调用函数

要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs,只有一个参数。

971130
来自专栏陈树义

如何唯一确定一个 Java 类?

今天偶然想起之前和朋友讨论过的一个问题:如何唯一确定一个 Java 类?我相信大多数朋友遇到这个问题的回答都是:类的全路径呗。但事实上,唯一确定一个 Java ...

25530
来自专栏desperate633

四张图搞懂Collection的类的层次关系Collection vs CollectionsCollection的类和接口的层次关系Map的类图类总结

首先,“Collection”和“Collections”是两个不同的概念。从下面的层次关系图也可以看到。“Collection”是Collection层次关系...

9130

扫码关注云+社区

领取腾讯云代金券