Kotlin的lateinit和by lazy的区别

news/2024/11/15 5:38:57/

一、lateinit

1.lateinit的使用

由于kotlin有严格的语法要求变量需要声明是否可以为null,但由于在实际的业务场景中,这个变量必须在某些时候才能做初始化操作,并且这个变量肯定不为null,如果为null,就是逻辑有问题了。这个时候可以使用lateinit来修饰这个变量。如果没有初始化就使用这个变量,那么就会抛出异常。

class LateInitExample {lateinit var value:String
}fun main() {val example = LateInitExample()// 如果没有赋值就使用,直接抛出异常。example.value = "lateinit example"println("${example.value}")
}

2.lateinit的具体实现

public class LateInitExample {private String value;public String getValue() {// 如果没有初始化过,就抛出异常if (value == null){throw new RuntimeException("lateinit property value has not been initialized");}return value;}public void setValue(String value) {// 这里要做非null检查this.value = value;}
}

我们知道使用kotlin的属性其实是在调用get和set方法,lateinit关键字其实就是对get和set方法做了一些操作。

注意lateinit不能修饰基本类型。

二、by lazy

by 和 lazy要单独拿出来看,不能当做一个整体来看。

by:这里涉及到了kotlin的委托中委托属性

lazy:一个kotlin的函数

1.属性委托

简单通俗理解就是这个变量的get,set都是委托给了另外一个类来去操作。

如果是var变量,必须要有getValue和setValue2个方法,val变量不需要setValue方法。

// 委托的类
class Delegate {operator fun getValue(thisRef: Any?, property: KProperty<*>): String {return "$thisRef, 这里委托了 ${property.name} 属性"}operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {println("$thisRef 的 ${property.name} 属性赋值为 $value")}
}

注意别和kotlin的get和set方法混淆了!!!!

语法是: val/var <属性名>: <类型> by <表达式>

Kotlin 标准库为几种有用的委托提供了工厂方法,延迟属性 Lazy就是其中之一。

https://www.runoob.com/kotlin/kotlin-delegated.html

2.lazy的实现

public actual fun <T> lazy(lock: Any?, initializer: () -> T): Lazy<T> = SynchronizedLazyImpl(initializer, lock)private class SynchronizedLazyImpl<out T>(initializer: () -> T, lock: Any? = null) : Lazy<T>, Serializable {private var initializer: (() -> T)? = initializer@Volatile private var _value: Any? = UNINITIALIZED_VALUE// final field is required to enable safe publication of constructed instanceprivate val lock = lock ?: thisoverride val value: Tget() {val _v1 = _valueif (_v1 !== UNINITIALIZED_VALUE) {@Suppress("UNCHECKED_CAST")return _v1 as T}return synchronized(lock) {val _v2 = _valueif (_v2 !== UNINITIALIZED_VALUE) {@Suppress("UNCHECKED_CAST") (_v2 as T)} else {val typedValue = initializer!!()_value = typedValueinitializer = nulltypedValue}}}override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUEoverride fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet."private fun writeReplace(): Any = InitializedLazyImpl(value)
}

看到这里,相信大家只剩下一个疑惑了,为什么没有getValue方法,不是说by的实现需要getValue方法吗?这里,kotlin使用了扩展函数来做。


// 这里返回value,就会执行实现类的override value get了。
public inline operator fun <T> Lazy<T>.getValue(thisRef: Any?, property: KProperty<*>): T = value

三、总结

从本质上来说,lateinit和by lazy的区别是体现在内存上:

lateinit修饰的属性,会在内存中创建,只不过没有赋值

by lazy修饰的属性,只有在使用的时候才会在内存中创建


http://www.ppmy.cn/news/11549.html

相关文章

xilinx srio ip学习笔记之再识srio

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 xilinx srio ip学习笔记之再识srio前言SRIO的理解IP核的理解前言 这段时间&#xff0c;随着对SRIO的学习&#xff0c;又有了更深的一点认识&#xff0c;不像一开始这么慌张了…

nodejs——MongoDB模块

MongoDB 是一个面向文档&#xff0c;schema 无关&#xff08;schema-less&#xff09;的数据库&#xff0c;它非常适合于 Node.js 应用以及云端部署。 与 MySQL 及 PostgreSQL 是根据固定的结构设计&#xff08;schema&#xff09;将数据存储在表中不同&#xff0c;MongoDB 可以…

设计模式面试题

工厂模式是我们最常用的实例化对象模式了&#xff0c;是用工厂方法代替new操作的一种模式,工厂模式在Java程序中可以说是随处可见。本文来给大家详细介绍下工厂模式 面向对象设计的基本原则&#xff1a; OCP&#xff08;开闭原则&#xff0c;Open-Closed Principle&#xff0…

【Linux】 gcc 、动态库和静态库,程序是如何链接的

文章目录前言一、gcc 是什么&#xff1f;二、使用步骤1.预编译2.编译3.汇编4.链接三、动静态库1.概念2.区别前言 在Linux环境下&#xff0c;除了学好编辑器 vim 的使用&#xff0c;还需要学会C语言的编译器 gcc 的功能&#xff0c;否则代码无法翻译成可执行程序。本文将介绍 gc…

RK3588平台开发系列讲解(日志篇)RK3588 syslog的使用

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、查看是否启用syslog.conf二、配置启用syslog.conf1、配置busybox2、添加配置文件3、编译buildroot烧录三、验证1、编写测试代码2、查看日志文件3、运行测试程序沉淀、分享、成长,让自己和他人都能有所收获!😄 …

详解结构体内存对齐

目录 前言 一、结构体内存对齐规则 二、 offsetof 宏 三、结构体内存对齐的原因 四、 修改默认对齐数 前言 引入问题&#xff1a; #include <stdio.h>struct S {char c1;int i;char c2; };int main() {printf("%zd\n", sizeof(struct S));return 0; } 程…

【主色提取】HSV 颜色空间与 RGB 颜色空间互相转化的公式和代码

系列文章目录 第二章 主色提取之颜色空间转化 目录 系列文章目录 文章目录 前言 一、HSV 和 RGB 颜色空间 二、颜色转化 1. RGB to HSV 2. HSV to RGB 三、 完整代码 前言 HSV 颜色空间和 RGB 颜色空间的转化。 一、HSV 和 RGB 颜色空间 RGB颜色使用的最多&#xff0…

优化SpringBoot程序启动速度

Spring Boot 程序优化 一、延迟初始化Bean 一般在 SpringBoot 中都拥有很多的耗时任务&#xff0c;比如数据库建立连接、初始线程池的创建等等&#xff0c;我们可以延迟这些操作的初始化&#xff0c;来达到优化启动速度的目的。Spring Boot 2.2 版本后引入 spring.main.lazy-i…