1. 简介

Kotlin 从众多编程语言中汲取了灵感,其中“对象”(object)就是这样一个特性。

在本文中,我们将快速了解 Kotlin 中的 object 是什么、它有哪些用法以及如何更好地使用它。

2. Kotlin 中的对象(Object)

在 Kotlin 和几乎所有的 JVM 语言中,类(class)是面向对象编程模型的核心概念。而 Kotlin 在此基础上引入了 object 的概念。

  • 类可以被多次实例化,创建多个对象;
  • 而 object 则始终表示一个单例实例(singleton instance)✅

也就是说,object 只能有一个实例,不多不少。

这个特性非常适合用于实现单例模式或者将一组功能打包封装:

object SimpleSingleton {
    val answer = 42
    fun greet(name: String) = "Hello, $name!"
}

assertEquals(42, SimpleSingleton.answer)
assertEquals("Hello, world!", SimpleSingleton.greet("world"))

⚠️ 注意:object 也支持可见性修饰符,可以像普通类一样控制封装性和访问权限:

object Counter {
    private var count: Int = 0

    fun currentCount() = count

    fun increment() {
        ++count
    }
}
Counter.increment()
println(Counter.currentCount())
// println(Counter.count) // ❌ 编译失败,count 是私有的

此外,object 还可以继承类或实现接口。这意味着它可以作为某个父类的唯一实例存在,这在很多场景下非常有用。

比如我们有一个无状态的比较器实现,就没必要每次都 new 一个新的实例:

object ReverseStringComparator : Comparator<String> {
    override fun compare(o1: String, o2: String) = o1.reversed().compareTo(o2.reversed())
}

val strings = listOf("Hello", "World")
val sortedStrings = strings.sortedWith(ReverseStringComparator)

3. 伴生对象(Companion Object)是什么?

伴生对象本质上就是一个特殊的 object,只不过它有一些额外的功能来简化开发。

  • 伴生对象必须定义在一个类内部;
  • 它可以有名字,也可以省略名字,默认名为 Companion
class OuterClass {
    companion object { // 等价于 "companion object Companion"
    }
}

3.1 伴生对象的访问方式

  • 在类内部可以直接访问伴生对象中的成员(无需加前缀);
  • 在外部可以通过 类名.成员名 的方式访问其可见成员:
class OuterClass {
    companion object {
        private val secret = "You can't see me"
        val public = "You can see me"
    }

    fun getSecretValue() = secret
}

assertEquals("You can see me", OuterClass.public)
// assertEquals("You can't see me", OuterClass.secret) // ❌ 无法访问私有字段

4. 静态字段与 @JvmStatic 注解

4.1 替代 Java 中的 static

伴生对象的主要用途之一就是替代 Java 中的静态方法和字段

但要注意:Kotlin 编译后的字节码中,这些“静态”字段并不会自动变成真正的 static 字段。

如果希望在 Java 中也能以静态方式调用,就需要加上 @JvmStatic 注解:

class StaticClass {
    companion object {
        @JvmStatic
        val staticField = 42
    }
}

如果不加 @JvmStatic,Java 代码就无法直接通过 StaticClass.staticField 访问该字段。

✅ 加上之后,Kotlin 会生成对应的 static 方法(如 getStaticField()),从而实现与 Java 的完全互操作。

5. 总结

  • Kotlin 的 object 提供了一种简洁的方式来实现单例;
  • 伴生对象进一步增强了这种能力,使代码更清晰、易维护;
  • 如果需要与 Java 互操作,记得使用 @JvmStatic 来暴露静态成员;

📌 示例代码可以在 GitHub 上找到:Baeldung Kotlin Tutorials - Core Kotlin Lang OOP


原始标题:Objects in Kotlin