Kotlin中的object:是什么、语法及单例对象的应用

作者: IT Sectr 发布日期: 2026-06-21 阅读时间: 9 分钟

object 在 Kotlin 中 — 是一种声明式创建单例对象的方式,具有延迟初始化和默认线程安全性。关键字 object 替代了具有单个实例的整个类,用于声明 singleton、companion object、匿名对象和静态工具类。根据 JetBrains Kotlin Documentation (2026),object declaration 是在 JVM 世界中实现单例最简单、最安全的方式。

要点

  • object — 用于声明具有单个实例的单例类的关键字
  • 延迟初始化 — object 在首次访问时创建,而非在类加载时
  • Companion object — Kotlin 中静态成员的类似物(没有 static 关键字)
  • Object expression — 用于即时重写方法的匿名对象
  • 线程安全 — object 的初始化保证是线程安全的

Kotlin 中的 object 是什么?

object 在 Kotlin 中 — 是一种特殊的声明形式,同时定义一个类并创建其唯一实例(单例)。它是 class declaration 和 instance creation 在一个结构中的混合体。

在 Java 中创建单例需要编写私有构造函数、静态字段、getInstance 方法并处理线程安全性。Kotlin object 用一行代码完成:object MySingleton { }。编译器自动使用 static initializer 机制在 JVM 字节码中生成线程安全的延迟初始化。

根据 Kotlin Language Specification (2026),object declaration 编译为一个 final 类,带有私有构造函数和在静态块中初始化的 INSTANCE 静态字段。这保证了 JVM 级别的初始化原子性。

单例对象(object declaration)

Object declaration(单例对象)使用关键字 object 后跟名称进行声明。对象体可以包含属性、方法、init 块,并可以继承其他类或接口。

kotlin
object DatabaseManager {
    private val connection: String = "jdbc:postgresql://localhost:5432/app"
    
    fun query(sql: String): List<Map<String, Any>> {
        // 执行查询
        return emptyList()
    }
}

// 使用
DatabaseManager.query("SELECT * FROM users")

DatabaseManager 的初始化发生在首次访问时 — 延迟且线程安全。不需要额外的同步代码。

object 的继承

Object 可以继承普通类和接口。这允许将 object 用作具有单个实例的抽象类或接口的实现。

kotlin
interface Logger {
    fun log(message: String)
}

object ConsoleLogger : Logger {
    override fun log(message: String) {
        println("[LOG] $message")
    }
}

Companion object

companion object — 是在类内部使用 companion 关键字声明的特殊 object。它替代 Kotlin 中的静态成员,因为该语言没有 static 关键字。

kotlin
class ApiClient {
    companion object {
        private const val BASE_URL = "https://api.example.com"
        
        fun create(): ApiClient {
            return ApiClient()
        }
    }
}

// 不创建 ApiClient 实例进行调用
val client = ApiClient.create()

Companion object 可以有名称(默认 Companion),可以实现接口,并可以通过扩展函数进行扩展。与 Java 中的静态方法不同,companion object 是一个完整的对象,可以作为参数传递或存储在变量中。

根据 Kotlin Best Practices (2026),companion object 用于工厂方法、常量和与类相关的静态工具类。建议避免过度使用 companion object — 对于不相关的工具类,最好使用顶层函数。

@JvmStatic 注解

了与 Java 兼容,companion object 的方法可以使用 @JvmStatic 进行注解。这会在 JVM 字节码中生成真正的静态方法,可从 Java 代码中访问而无需 Companion 语法。

Object expressions(匿名对象)

Object expression — 是在现场创建的匿名对象,用于重写类或接口的方法,而无需声明单独的命名类。

kotlin
val handler = object : Runnable {
    override fun run() {
        println("任务已执行")
    }
}

thread(handler)

Object expressions 与 object 声明不同,因为它们在每次执行时创建一个新实例。它们不是单例,也没有名称。匿名对象可以从闭包中捕获变量,就像 lambda 表达式一样。

与 Java 中匿名类只能继承一个类型不同,Kotlin object expression 可以同时继承 多个 类型。

kotlin
interface Clickable {
    fun click()
}

abstract class View {
    abstract fun render()
}

val button = object : View(), Clickable {
    override fun render() = println("渲染按钮")
    override fun click() = println("按钮已点击")
}

实际使用场景

Object — 是 Kotlin 中最通用的结构之一,用于许多场景。

单例仓库

Android 项目中,object 通常用于声明 Repository,在其中不需要多个实例。单个实例保证了数据的一致性。

kotlin
object UserRepository {
    fun getUser(id: Int): User? {
        // 获取用户
        return null
    }
}

通过 companion object 的工厂方法

Companion object 与工厂方法 — 是多个构造函数的替代方案。命名的工厂方法使代码自文档化。

kotlin
data class GsonParser {
    companion object {
        fun create(): GsonParser = GsonParser()
        fun createPretty(): GsonParser = GsonParser()
    }
}

常量和枚举

Object 可以作为常量的容器,替代 Java 中的 static final 字段。object 支持继承,允许创建配置层次结构。

根据 Kotlin Standard Library (2026),object declaration 是在 Kotlin 中创建单例的最高效方式,在速度上超过 "double-checked locking" 实现,并且与 Java 中的 enum 单例相当。

常见问题

object 与普通类有什么不同?

Object 同时声明一个类并创建其唯一实例。普通类可以有通过构造函数创建的多个实例。

object declaration 何时初始化?

延迟 — 在首次访问对象时。在此之前,不会分配内存,也不会执行 init 块中的代码。

object 可以有构造函数吗?

不能,object 不能有显式构造函数。初始化在 init 块中进行,该块在首次访问对象时调用一次。

companion object 和普通 object 有什么不同?

companion object — 是在类内部声明的 object。其成员通过类名即可访问,无需创建实例,这替代了 Java 的静态成员。

object declarations 在多线程环境中安全吗?

是的,object 的初始化由于 JVM 的静态初始化器是完全线程安全的。不需要额外的同步。

总结

  • object — 具有延迟和线程安全初始化的声明式单例
  • companion object — Kotlin 中的静态成员、工厂方法、常量
  • Object expression — 从闭包捕获变量的现场匿名对象
  • 继承 — object 可以继承类和接口,包括多个类型
  • 性能 — 通过 JVM static initializer 初始化,没有 double-checked locking 的开销
  • 应用 — 单例服务、仓库、常量、工厂、监听器适配器
  • 限制 — 没有显式构造函数,整个 JVM 只有一个实例

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读