Skip to content

对象表达式与单例

源:Object 声明参考

Kotlin 将单例模式和匿名内部类统一整合在 object 关键字之下。

对象声明 (Object Declarations) - 单例模式

Kotlin 原生支持单例。通过 object 声明的类,将在第一次被访问时懒加载初始化,且由 JVM 保证线程安全

kotlin
object NetworkManager {
    private val client = OkHttpClient()
    
    fun request(url: String) { /*...*/ }
}

// 使用
NetworkManager.request("https://google.com")

Data Object (Kotlin 1.9+)

用于密封类层级或需要这就 toString() 输出的单例。

kotlin
// 普通 object toString() 输出: Content@5f184fc
object Content 

// Data object toString() 输出: Loaded
data object Loaded

伴生对象 (Companion Objects) - 静态成员

Kotlin 类没有 static 成员。作为替代,我们在类内部声明一个伴生对象。

kotlin
class User {
    companion object {
        const val TABLE_NAME = "users"
        fun createDefault() = User()
    }
}

// 调用 (看起来像静态方法)
User.createDefault()

@JvmStatic

为了方便 Java 调用,建议给伴生对象的方法加上 @JvmStatic 注解,这样 Java 代码可以直接调用 User.createDefault() 而不需要 User.Companion.createDefault()

对象表达式 (Object Expressions) - 匿名内部类

对象表达式用于创建一个继承自某个类或实现接口的匿名类的实例。

kotlin
val listener = object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) { /*...*/ }
    override fun mouseEntered(e: MouseEvent) { /*...*/ }
}

闭包能力

与 Java 的匿名内部类不同,Kotlin 的对象表达式可以访问并修改非 final 的局部变量。

kotlin
var clickCount = 0
button.setOnClickListener(object : OnClickListener {
    override fun onClick(v: View) {
        clickCount++ // ✅ 直接修改外部变量
    }
})

深度对比:Object vs Companion Object

特性ObjectCompanion Object
初始化时机第一次访问该对象时所在的外部类被加载时
类名关联独立类名依附于外部类
接口实现可以实现接口可以实现接口
扩展函数只能扩展该对象可以为外部类扩展“静态方法”