You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何在所有属性setter调用时统一执行指定函数?

解决方案:统一更新modified属性

当然可以统一处理这三个属性的setter逻辑,下面提供两种简洁的实现方式,避免重复代码:

方法1:提取公共更新方法,自定义setter

先定义一个私有方法封装modified的更新逻辑,然后在address、name、owner的setter中调用这个方法,实现代码复用:

import java.time.LocalDateTime
import kotlin.concurrent.sleep

class Company(
    address: String,
    name: String,
    owner: String
) {
    var address: String = address
        set(value) {
            field = value
            updateModified()
        }

    var name: String = name
        set(value) {
            field = value
            updateModified()
        }

    var owner: String = owner
        set(value) {
            field = value
            updateModified()
        }

    var modified = LocalDateTime.now()
        private set // 禁止外部直接修改该属性

    private fun updateModified() {
        modified = LocalDateTime.now()
    }
}

fun main() {
    val company = Company("Adrd", "test", "Jack")
    println(company.modified) // 打印初始时间
    sleep(3000)
    company.address = "address2"
    println(company.modified) // 打印更新后的时间(比初始时间晚约3秒)
}

说明

  • 用field关键字访问属性的幕后字段,这是Kotlin自定义setter的标准写法
  • updateModified()作为私有方法,把更新modified的逻辑抽离出来,三个属性的setter统一调用它
  • 给modified添加private set,确保只有类内部能修改该属性,避免外部误操作

方法2:使用委托属性简化代码

如果觉得自定义setter仍有重复代码,可以用Kotlin的Delegates.observable委托,让三个属性共用同一段更新逻辑:

import java.time.LocalDateTime
import kotlin.properties.Delegates
import kotlin.concurrent.sleep

class Company(
    address: String,
    name: String,
    owner: String
) {
    var modified = LocalDateTime.now()
        private set

    // 封装更新modified的逻辑为lambda
    private val updateModified = { _: Any?, _: Any?, _: Any? ->
        modified = LocalDateTime.now()
    }

    var address: String by Delegates.observable(address, updateModified)
    var name: String by Delegates.observable(name, updateModified)
    var owner: String by Delegates.observable(owner, updateModified)
}

fun main() {
    val company = Company("Adrd", "test", "Jack")
    println(company.modified)
    sleep(3000)
    company.name = "newTest"
    println(company.modified)
}

说明

  • Delegates.observable会在属性值被修改时自动触发传入的回调lambda
  • 三个属性共用同一个委托逻辑,代码更简洁,后续若要调整更新规则,只需修改一处lambda即可

两种方法都能满足你的需求,第一种逻辑直观,第二种代码更精简,可根据个人习惯选择。

内容的提问来源于stack exchange,提问作者George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 04:42:14