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