by 和by lazy 懒加载

一、by 两种使用场景

  1. 委托类(类委托) class A : B by C把接口方法实现,全权委托给另一个对象去执行,简化代码复用。
  2. 委托属性 var/val 变量:类型 by 委托类把属性的 get/set 逻辑交给委托类实现。

1、类委托 by

意思:自己不想写方法,直接交给别人帮我干活

1. 先写一个干活的接口

kotlin

kotlin 复制代码
interface Drive {
    fun drive() // 开车
}
2. 找一个会开车的人

kotlin

kotlin 复制代码
class Driver : Drive {
    override fun drive() {
        println("老司机稳稳开车")
    }
}
3. 老板不会开车,委托司机开

kotlin

kotlin 复制代码
// 老板把开车这件事,全权委托给司机
class Boss(driver: Drive) : Drive by driver
4. 调用

kotlin

kotlin 复制代码
fun main(){
    val laoban = Boss(Driver())
    laoban.drive() // 直接司机执行
}

直白理解:我实现接口,但我不写代码,交给别人实现

2、属性委托 by(最常用)

一句话理解

变量的 get 和 set,交给别人去做


超简单例子(背这个)

kotlin

kotlin 复制代码
class Person {
    // name 的取值、赋值 全部交给 Delegate 管理
    var name: String by Delegate()
}

// 委托类:专门管变量的 存 和 取
class Delegate {
    // 取值
    operator fun getValue(thisRef: Any?, prop: KProperty<*>): String {
        return "我是取值"
    }

    // 赋值
    operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) {
        println("赋值了:$value")
    }
}

使用

kotlin

scss 复制代码
val p = Person()

p.name = "张三"   // 走 setValue
println(p.name)   // 走 getValue

输出

plaintext

复制代码
赋值了:张三
我是取值

二、by lazy 懒加载(必考)

1. 用法

kotlin

kotlin 复制代码
val name: String by lazy {
    "初始化值"
}

第一次调用才执行 lambda 初始化,之后直接拿缓存值

2. 三种模式

kotlin

csharp 复制代码
// 1. 线程安全(默认),多线程单例初始化
by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { }

// 2. 不加锁,单线程使用最快
by lazy(LazyThreadSafetyMode.NONE) { }

// 3. 多线程并行,谁先初始化谁生效
by lazy(LazyThreadSafetyMode.PUBLICATION) { }

3. 底层实现原理(面试背诵)

  1. 本质是属性委托 ,底层实现 Lazy 接口

  2. 内部用volatile 标记缓存值,保证可见性

  3. 内部做空判断

    • 变量未初始化 → 执行 lambda 赋值
    • 已初始化 → 直接返回已有值
  4. 只初始化一次,延迟加载,节省内存

  5. 只能修饰 val 只读属性,不能用于 var

4. 特点

  • 延迟初始化,用到才创建
  • 线程安全默认实现
  • 全局单例效果,全局共用同一个对象

三、极简面试答案

  1. by 关键字用于类委托属性委托
  2. by lazy 是属性委托最常用实现,延迟懒加载
  3. 原理:首次访问执行初始化并缓存,后续直接取值,内部通过空校验 + 线程安全策略实现,仅支持只读 val 属性。
相关推荐
三少爷的鞋3 小时前
Android 架构系列之MVVM 和 MVI 算架构吗?
android·kotlin
只可远观21 小时前
Android 自动埋点(页面打开 / 关闭 + 点击事件)完整方案
android·kotlin
aqi001 天前
FFmpeg开发笔记(一百零二)国产的音视频移动开源工具FFmpegAndroid
android·ffmpeg·kotlin·音视频·直播·流媒体
阿巴斯甜1 天前
子协程的异常传播(CoroutineExceptionHandler ):
kotlin
alexhilton1 天前
Android上的ZeroMQ:用发布/订阅模式连接Linux服务
android·kotlin·android jetpack
Fate_I_C2 天前
View Binding的基础使用
android·kotlin·viewbinding
zhangphil2 天前
Android Coil 3 extend ImageRequest‘s custom method/function,Kotlin
android·kotlin
Empty-Filled2 天前
Prompt改版后怎么回归:一套测试集和评分方法
回归·kotlin·prompt
阿巴斯甜3 天前
launch 和 async 内部都是串行,为什么还能实现并发?
kotlin