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 属性。
相关推荐
杉氧15 小时前
Ktor 全栈之路 (5):JWT 认证全流程实战 —— 打造安全通信闭环
android·架构·kotlin
alexhilton1 天前
MVI模式的完整历史、误解和现代Android范式
android·kotlin·android jetpack
pengyu2 天前
【Kotlin 协程修仙录 · 金丹境 · 后阶】 | 异常防火墙:supervisorScope 与异常隔离的终极奥义
android·kotlin
夏沫琅琊2 天前
Jetpack Compose + 原生 PDF API 从零搭一个 Android 工具应用 (一)
android·pdf·kotlin
疏狂难除2 天前
JetBrains IDE插件开发教程(五)——File Header
ide·kotlin
Kapaseker3 天前
Android CLI 完全指南
android·kotlin
Coffeeee4 天前
Android功耗优化,哪些代码会让你的机子发热又耗电
android·架构·kotlin
Android打工仔4 天前
Kotlin 编译器是如何把 suspend 函数变成状态机的?
kotlin
Android打工仔4 天前
一个 suspend 函数,为什么会变成一个普通函数?
kotlin
苦瓜花4 天前
【Kotlin】初入门
android·开发语言·kotlin