一文弄懂Kotlin中的by关键字

在 Kotlin 中,by 关键字用于实现委托模式(Delegation)​ ,它允许将某些操作或责任委托给另一个对象来处理。by 主要有两种用途:​类委托属性委托


1. 类委托(Class Delegation)

通过 by 关键字,可以将类的接口实现委托给另一个对象。这样可以在不继承的情况下复用现有类的功能。

示例:

kotlin 复制代码
interface Animal {
    fun makeSound()
}

class Dog : Animal {
    override fun makeSound() {
        println("Woof!")
    }
}

// 通过 by 将 Animal 接口的实现委托给 dog 对象
class Robot(private val dog: Dog) : Animal by dog {
    fun move() {
        println("Robot is moving")
    }
}

fun main() {
    val dog = Dog()
    val robot = Robot(dog)
    robot.makeSound() // 实际调用的是 Dog 的 makeSound()
    robot.move()      // Robot 的独有方法
}
  • 作用Robot 类通过 by dog 委托了 Animal 接口的实现,无需手动重写 makeSound()
  • 优势:避免重复代码,优先组合而非继承。

2. 属性委托(Property Delegation)

通过 by 将属性的 getter/setter 逻辑委托给一个委托对象 ​(需实现 getValue()setValue() 方法)。Kotlin 标准库提供了几种常用委托:

常见用途:

(1)懒加载委托 lazy

属性在首次访问时初始化。

kotlin 复制代码
val heavyData: String by lazy {
    println("Computing heavy data...")
    "Heavy Result"
}

fun main() {
    println(heavyData) // 第一次访问时计算并缓存
    println(heavyData) // 直接返回缓存结果
}
(2)观察者委托 Delegates.observable

属性变化时触发回调。

kotlin 复制代码
import kotlin.properties.Delegates

var name: String by Delegates.observable("Alice") { _, old, new ->
    println("Name changed: $old -> $new")
}

fun main() {
    name = "Bob" // 输出: Name changed: Alice -> Bob
}
(3)非空校验委托 Delegates.notNull

延迟初始化但确保非空。

kotlin 复制代码
var age: Int by Delegates.notNull<Int>()

fun main() {
    age = 30
    println(age) // 必须先赋值,否则抛 IllegalStateException
}
(4)自定义委托

实现 ReadWritePropertyReadOnlyProperty 接口。

kotlin 复制代码
class StringDelegate(private var value: String) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        println("Getting value: $value")
        return value
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) {
        println("Setting value: $newValue")
        value = newValue
    }
}

var text by StringDelegate("Default")

fun main() {
    println(text) // 输出: Getting value: Default
    text = "New"  // 输出: Setting value: New
}

关键点总结:

  • 类委托 :通过 by 将接口实现委托给其他对象。
  • 属性委托 :将属性的访问逻辑委托给 lazyobservable 或自定义对象。
  • 优势:减少重复代码,实现关注点分离(如懒加载、观察模式等)。

通过 by,Kotlin 以简洁的语法实现了强大的委托模式,是 Kotlin 特色功能之一。

相关推荐
Sirens.4 小时前
从参考 iCost 到做自己的 OneLedger:一个 Android 本地记账 App 的开发记录
android·kotlin·room·jetpack compose·记账 app
Hrain-AI8 小时前
2026 企业 AI 编程智能体实战:Codex 与 Claude Code
开发语言·人工智能·kotlin
btown3 天前
Kotlin 版 MyBatis-Plus 查询优雅解决方案
kotlin
小二·4 天前
车载数字座舱实战:用魔珐星云打造下一代智能驾乘助手(附 Android/Kotlin 完整代码)
开发语言·kotlin
我命由我123454 天前
Android 开发问题:java.lang.NoSuchMethodError:No virtual method readAllBytes()
android·java·java-ee·kotlin·android studio·android-studio·android runtime
Kapaseker4 天前
你是不是还没用过 select?实战 Kotlin select
android·kotlin
plainGeekDev5 天前
synchronized → Coroutines
android·java·kotlin
唐青枫5 天前
Java Gradle 实战指南:从 Wrapper、Kotlin DSL 到 Spring Boot 多模块构建
java·kotlin·gradle
帅次6 天前
Kotlin Flow 与 StateFlow:UI 单向数据流基础
开发语言·ui·kotlin·stateflow·onlifecycle
Kapaseker6 天前
Sequence 一定比 List 快?等等,我们先从基础讲起
android·kotlin