Kotlin 定义类与field关键

在 Kotlin 中,类的属性与 field 关键字的使用是语法设计中的重要特性。以下是详细解析:


一、Kotlin 类的定义

Kotlin 通过 class 关键字定义类,属性默认自动生成 getter/setter

kotlin 复制代码
class Person {
    var name: String = "默认值" // 自动生成 getter 和 setter
    val age: Int = 0          // 只读属性,仅生成 getter
}

二、field 关键字的作用

field 是 Kotlin 中用于访问属性‌幕后字段 ‌(backing field)的关键字,仅在属性的 get()set() 自定义逻辑中使用。

1. ‌**隐式使用 field**‌

默认情况下,Kotlin 会自动为属性生成幕后字段:

csharp 复制代码
var counter = 0
    // 等价于以下隐式代码:
    // get() = field
    // set(value) { field = value }

2. ‌**显式使用 field**‌

当自定义 get()set() 时,必须通过 field 访问实际存储值:

javascript 复制代码
var name: String = ""
    get() = field.uppercase()  // 返回大写值,但不修改存储值
    set(value) {
        field = value.trim()   // 赋值前去除首尾空格
    }

三、使用 field 的注意事项

1. ‌避免递归调用

直接使用属性名会触发 getter/setter,导致递归:

javascript 复制代码
// ❌ 错误示例:导致栈溢出
var counter = 0
    set(value) {
        if (value >= 0) this.counter = value // 递归调用 set()
    }

// ✅ 正确写法:使用 field
var counter = 0
    set(value) {
        if (value >= 0) field = value
    }

2. ‌仅限在 get()/set() 中使用

field 不可在类其他方法中直接访问:

kotlin 复制代码
class Demo {
    var data = 0
    
    fun update() {
        field = 10 // ❌ 编译错误:field 只能在 getter/setter 中使用
    }
}

四、无幕后字段的场景

如果属性不依赖幕后字段存储数据(例如通过计算获得值),则无需使用 field

kotlin 复制代码
val isAdult: Boolean
    get() = age >= 18  // 直接依赖其他属性,无需 field
    
    
 
// 计算属性  下面这样写 get函数覆盖了 field 内容本身,相当于field失效了,无用了,以后用不到了
var number2 : Int = 0
    get() = (1..1000).shuffled().first() // 从1到1000取出随机值 返回给 getNumber2()函数
/*
    背后隐式代码:
    为什么没有看到 number2 属性定义?
    答:因为属于 计算属性 的功能,根本在getNumber2函数里面,就没有用到 number2属性,所以 number2属性 失效了,无用了,以后用不到了

     public int getNumber2() {
        return (1..1000).shuffled().first()java的随机逻辑 复杂 ;
   }
 */

五、与 Java 的对比

特性 Java Kotlin
字段定义 显式声明为 private 字段 自动生成幕后字段,通过 field 访问
访问控制 手动实现 getter/setter 默认自动生成,可自定义逻辑
属性访问 直接访问字段或调用方法 统一通过属性名访问,隐藏底层实现

六、完整示例

ini 复制代码
class KtBase69 {

var name = "Derry"
    get() = field
    set(value) {
        field = value
    }
/* 背后做的事情:

   @NotNull
   private String name = "Lili";

   public void setName( @NotNull String name) {
        this.name = name;
   }

   @NotNull
   public String getName() {
        return this.name;
   }

 */

var value = "ABCDEFG"
    // 下面的隐式代码,不写也有,就是下面这个样子
    get() = field
    set(value) {
        field = value
    }

var info = "abcdefg ok is success"
    get() = field.capitalize() // 把首字母修改成大写
    set(value) {
        field = "**【$value】**"
    }
    

/* 背后做的事情:
    @NotNull
    private String info = "abcdefg ok is success";

    public void setInfo( @NotNull String info) {
        this.info = "**【" + info + "】**";
    }

    @NotNull
    public String getInfo() {
        return StringKt.capitalize(this.info)
    }

 */


}

class User {

    var email: String = ""
        set(value) {
            field = if (value.contains("@")) value else "invalid"
        }

    val info: String
        get() = "Email: $email"
}

//Kotlin 定义类与field关键
fun main(){

    // 背后隐式代码:new KtBase69().setName("wangwu");
    val ktBase69 = KtBase69()
    ktBase69.name = "wangwu"
    
    println(ktBase69.name)
    println("value:${ktBase69.value}")
    println("info: ${ktBase69.info}")

    val user = User()
    user.email = "test"  // 自动调用 setter,赋值 "invalid"
    println(user.info)
}

七、总结

  • ‌**field 的作用**‌:在自定义 get()/set() 中访问属性的实际存储值。
  • 使用场景‌:需要控制属性读写逻辑时(如数据校验、格式化)。
  • 避免错误 ‌:在自定义访问器中,始终用 field 替代属性名以避免递归。
相关推荐
crmscs2 分钟前
剪映永久解锁版/电脑版永久会员VIP/安卓SVIP手机永久版下载
android·智能手机·电脑
localbob5 分钟前
杀戮尖塔 v6 MOD整合版(Slay the Spire)安卓+PC端免安装中文版分享 卡牌肉鸽神作!杀戮尖塔中文版,电脑和手机都能玩!杀戮尖塔.exe 杀戮尖塔.apk
android·杀戮尖塔apk·杀戮尖塔exe·游戏分享
机建狂魔9 分钟前
手机秒变电影机:Blackmagic Camera + LUT滤镜包的专业级视频解决方案
android·拍照·摄影·lut滤镜·拍摄·摄像·录像
hudawei9969 分钟前
flutter和Android动画的对比
android·flutter·动画
lxysbly2 小时前
md模拟器安卓版带金手指2026
android
儿歌八万首3 小时前
硬核春节:用 Compose 打造“赛博鞭炮”
android·kotlin·compose·春节
消失的旧时光-19435 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
Jinkxs5 小时前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&5 小时前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin
LDORntKQH6 小时前
基于深度强化学习的混合动力汽车能量管理策略 1.利用DQN算法控制电池和发动机发电机组的功率分配 2
android