You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何声明单例实例?与单例类声明方式是否一致?

Kotlin单例声明的核心规则

Kotlin中*object关键字的对象声明语法*,本身就同时完成了单例类定义、单例实例生成两个步骤,默认是线程安全、首次访问懒加载的,不存在无参场景下分开写“单例类”“单例实例”两套代码的要求。

无参单例声明的实际效果

你面试时写的代码:

object Ant{
}

已经是合法的完整无参单例实现,编译器会自动完成两件事:

  • 生成一个不可被外部继承、不可手动实例化的类,也就是常说的Singleton类
  • 生成这个类的唯一静态实例,也就是Singleton实例,首次访问Ant时完成初始化,线程安全

你直接使用Ant这个名称,拿到的就是这个单例的唯一实例,不需要额外声明。比如调用方法、访问属性时直接写Ant.xxx()即可,不需要额外手动实例化或者写getInstance()方法。

“编写Singleton实例”要求的两种常见考察方向

你当时重复写新的object what{}是错误的,因为这是定义了另一个完全无关的单例,和之前的Ant没有关联。通常面试官提这个要求,是以下两种考察方向之一:

  1. 考察对object语法本质的理解:只需要明确说明Ant本身就是对应的单例实例,不需要额外定义即可。很多有Java开发背景的面试官会习惯Java里“先定义类,再写getInstance取实例”的模式,容易误以为Kotlin的object只声明了类,这时候只要讲清编译器的自动生成逻辑即可。
  2. 考察带参数单例的实现:普通object声明不支持传入构造参数,如果单例初始化需要依赖外部参数,就需要分开声明类和实例持有逻辑,参考实现如下:
    // Singleton类声明,构造方法私有禁止外部实例化
    class ConfigSingleton private constructor(val configPath: String) {
        // 伴生对象里持有单例实例,实现实例获取逻辑
        companion object {
            @Volatile
            private var instance: ConfigSingleton? = null
    
            fun getInstance(path: String): ConfigSingleton {
                // 双检锁保证线程安全、单例唯一
                return instance ?: synchronized(this) {
                    instance ?: ConfigSingleton(path).also { instance = it }
                }
            }
        }
    
        fun readConfig() {
            println("read config from $configPath")
        }
    }
    
    这种场景下,ConfigSingleton是单例类,通过ConfigSingleton.getInstance("/path/to/config")拿到的对象就是对应的单例实例,二者声明方式确实不同。

两种单例写法的差异总结

  • 无参单例:直接用object 名称声明即可,单例类和单例实例由编译器同步生成,声明方式完全一致,不需要额外写实例定义代码。
  • 带参单例:需要先声明私有构造的普通类,再在伴生对象中手动实现线程安全的实例持有、获取逻辑,类和实例的声明逻辑是分开的。

内容的提问来源于stack exchange,提问作者user19219454

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:16:02