Kotlin-延迟初始化

2020-12-30  本文已影响0人  有腹肌的豌豆Z

Koltin中属性在声明的同时也要求要被初始化,否则会报错。例如以下代码:

private var name0: String //报错
private var name1: String = "xiaoming" //不报错
private var name2: String? = null //不报错

可是有的时候,我并不想声明一个类型可空的对象,而且我也没办法在对象一声明的时候就为它初始化,那么这时就需要用到Kotlin提供的延迟初始化。Kotlin中有两种延迟初始化的方式。一种是 lateinit var,一种是by lazy


lateinit 延迟初始化

private lateinit var name: String
lateinit在Android中使用
private lateinit var s: String
private val ss:String by lazy { "132" }

fun main() {
    print("懒加载 ss = $ss")
    try {
        print("没有初始化 是s =  $s  \n")   // 必须要初始化之后才能使用
    }catch (e:Exception){
        e.printStackTrace()
    }
    s = "123456"
    print("初始化之后的  s =  $s")
}
class MainActivity : AppCompatActivity() {

    private lateinit var bt: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        bt = findViewById(R.id.bt)
        bt.setOnClickListener {
            Toast.makeText(baseContext, "click", Toast.LENGTH_SHORT).show()
        }
    }
}

lazy 延迟初始化

by lazy本身是一种属性委托。属性委托的关键字是byby lazy的写法如下:

//用于属性延迟初始化
val name: Int by lazy { 1 }
 
//用于局部变量延迟初始化
public fun foo() {
    val bar by lazy { "hello" }
    println(bar)
}

在 Android 中使用

class MainActivity : AppCompatActivity() {

   private val bt by lazy {
        findViewById<Button>(R.id.bt)
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        bt.setOnClickListener {
            Toast.makeText(baseContext, "click", Toast.LENGTH_SHORT).show()
        }
    }
}

lazy 延迟模式

在使用 lazy 延迟初始化的时候,Kotlin提供了3中模式,源码如下:

public actual fun <T> lazy(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy<T> =
    when (mode) {
        LazyThreadSafetyMode.SYNCHRONIZED -> SynchronizedLazyImpl(initializer)
        LazyThreadSafetyMode.PUBLICATION -> SafePublicationLazyImpl(initializer)
        LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer)
    }

private val sss:String by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { "最后一个函数 可以放在外面 " }

当我们模式都不用的情况下,默认使用 LazyThreadSafetyMode.SYNCHRONIZED 线程安全模式。源码如下:

public actual fun <T> lazy(initializer: () -> T): Lazy<T> = SynchronizedLazyImpl(initializer)

几个例子,使用延迟模式创建一个单例

class Manager {

    init {
        Log.e("zhaoyanjun:inin", "初始化")
    }

    companion object {
        val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
            Manager()
        }
    }
}

上一篇下一篇

猜你喜欢

热点阅读