Kotlin的lateinit和by lazy的区别(kotlin trim)(kotlin的let和apply的区别)

花匠人从多个角度为你分享Kotlin的lateinit和by lazy的区别(kotlin trim)(kotlin的let和apply的区别),让你更加了解Kotlin的lateinit和by lazy的区别(kotlin trim)(kotlin的let和apply的区别),包含生活百科相关的生活技巧、生活小窍门、生活小妙招等生活百科知识。

  本篇文章为你整理了Kotlin的lateinit和by lazy的区别(kotlin trim)(kotlin的let和apply的区别)的详细内容,包含有Kotlin的lateinit和by lazy的区别(kotlin trim) kotlin和typescript dart和kotlin kotlin it与this等,让你从多个方面了解Kotlin的lateinit和by lazy的区别(kotlin trim)(kotlin的let和apply的区别),希望对你有帮助。

  

一、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  lazy(lock: Any?, initializer: () -> T): Lazy = SynchronizedLazyImpl(initializer, lock)private class SynchronizedLazyImpl(initializer: () -> T, lock: Any? = null) : Lazy, Serializable { private var initializer: (() -> T)? = initializer @Volatile private var _value: Any? = UNINITIALIZED_VALUE // final field is required to enable safe publication of constructed instance private val lock = lock ?: this override val value: T get() { val _v1 = _value if (_v1 !== UNINITIALIZED_VALUE) { @Suppress("UNCHECKED_CAST") return _v1 as T } return synchronized(lock) { val _v2 = _value if (_v2 !== UNINITIALIZED_VALUE) { @Suppress("UNCHECKED_CAST") (_v2 as T) } else { val typedValue = initializer!!() _value = typedValue initializer = null typedValue } } } override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE override 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  Lazy.getValue(thisRef: Any?, property: KProperty<*>): T = value

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

 

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

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

  

  以上就是Kotlin的lateinit和by lazy的区别(kotlin trim)(kotlin的let和apply的区别)的全部内容,想要了解更多Kotlin的lateinit和by lazy的区别(kotlin trim)(kotlin的let和apply的区别)相关的内容,请持续关注我们。

以上就是花匠人为你整理的Kotlin的lateinit和by lazy的区别(kotlin trim)(kotlin的let和apply的区别),如果你还想了解更多生活百科知识,请持续关注花匠人。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: