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

为何Kotlin中User类的fullName无法随firstName/lastName动态变化?

问题:修改firstName/lastName后fullName不更新的原因及解决方法

代码示例

User类定义

open class User(var firstName: String, var lastName: String) {

var fullName = "$firstName $lastName"
    get() = "Name: $field"
    set(value){
        if(value.startsWith("Jon")){
            field = "Jon Doe"
        }else{
            field = value
        }
    }
}

测试代码

val person1 = User("Mark", "Zuck")

println(person1.fullName)
// 输出:Name: Mark Zuck

person1.firstName = "Bill"

println(person1.firstName)
// 输出:Bill

println(person1.fullName)
// 输出:Name: Mark Zuck

person1.lastName = "Gates"

println(person1.fullName)
// 输出:Name: Mark Zuck

用户疑问

修改firstName或lastName时,fullName并未随之变化,是因为fullName被getter和setter绑定,只能通过直接访问fullName来修改它吗?


解答

问题原因

你当前的fullName只是在类初始化时,把当时的firstName和lastName拼接结果赋值给了幕后字段field。之后修改firstName或lastName时,不会自动更新field的值,而fullName的getter只是返回基于这个静态field的字符串,自然不会跟着变化。这和getter/setter绑定无关,是初始化逻辑没有建立动态关联导致的。

解决方案

根据需求,有两种常见处理方式:

方式1:动态计算fullName(推荐)

如果希望fullName始终反映最新的firstName和lastName,可以去掉fullName的字段存储,让getter每次调用时动态拼接:

open class User(var firstName: String, var lastName: String) {
    var fullName: String
        get() = "Name: $firstName $lastName"
        set(value) {
            // 可选:支持通过设置fullName反向修改firstName和lastName
            val nameContent = if (value.startsWith("Name: ")) value.substring(6) else value
            if (nameContent.startsWith("Jon")) {
                firstName = "Jon"
                lastName = "Doe"
            } else {
                val parts = nameContent.split(" ", limit = 2)
                if (parts.size == 2) {
                    firstName = parts[0]
                    lastName = parts[1]
                }
            }
        }
}

这样每次获取fullName时,都会用当前最新的firstName和lastName生成结果,修改这两个属性后,fullName会自动同步更新。

方式2:修改firstName/lastName时手动更新fullName

如果需要保留fullName的字段存储(比如有自定义setter逻辑),可以给firstName和lastName添加setter,在它们被修改时同步更新fullName:

open class User(firstName: String, lastName: String) {
    var firstName: String = firstName
        set(value) {
            field = value
            // 更新fullName的字段值
            fullName = "$firstName $lastName"
        }
    var lastName: String = lastName
        set(value) {
            field = value
            // 更新fullName的字段值
            fullName = "$firstName $lastName"
        }
    
    var fullName = "$firstName $lastName"
        get() = "Name: $field"
        set(value){
            if(value.startsWith("Jon")){
                field = "Jon Doe"
            }else{
                field = value
            }
        }
}

这种方式下,修改firstName或lastName会触发它们的setter,进而更新fullName的幕后字段,确保getter返回最新值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:57:17