kotlin
Kotlin中实现单例的几种常见方式
在Kotlin中,实现单例模式比Java更加简洁和优雅。以下是Kotlin中实现单例的几种常见方式:
1. 对象声明(Object Declaration) - 最推荐的方式
object Singleton {init {println("Singleton initialized") }fun doSomething() {println("Doing something")}
}// 使用
Singleton.doSomething()
特点:
- 线程安全,由Kotlin保证
- 懒加载(首次访问时初始化)
- 简洁明了,推荐使用
2. 伴生对象(Companion Object)实现
class Singleton private constructor() {companion object {val instance: Singleton by lazy { Singleton() }}fun doSomething() {println("Doing something")}
}// 使用
Singleton.instance.doSomething()
特点:
- 使用
by lazy
实现懒加载 - 线程安全(默认情况下
lazy
是线程安全的) - 可以更灵活地控制初始化过程
3. 双重校验锁模式(Double-Checked Locking)
class Singleton private constructor() {companion object {@Volatileprivate var instance: Singleton? = nullfun getInstance(): Singleton {return instance ?: synchronized(this) {instance ?: Singleton().also { instance = it }}}}fun doSomething() {println("Doing something")}
}// 使用
Singleton.getInstance().doSomething()
特点:
- 线程安全
- 性能优化(只在第一次创建时同步)
- 适用于需要复杂初始化逻辑的场景
4. 枚举单例(Enum Singleton)
enum class Singleton {INSTANCE;fun doSomething() {println("Doing something")}
}// 使用
Singleton.INSTANCE.doSomething()
特点:
- 线程安全
- 防止反射攻击
- 序列化/反序列化安全
- 但Kotlin中较少使用,因为对象声明通常更简洁
5. 使用Lazy委托属性
class Singleton private constructor() {companion object {val instance: Singleton by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {Singleton()}}fun doSomething() {println("Doing something")}
}// 使用
Singleton.instance.doSomething()
特点:
- 显式指定线程安全模式
- 可以自定义初始化逻辑
- 懒加载
各实现方式对比
实现方式 | 线程安全 | 懒加载 | 防止反射攻击 | 代码简洁性 | 适用场景 |
---|---|---|---|---|---|
对象声明 | ✔️ | ✔️ | ❌ | ⭐⭐⭐⭐⭐ | 大多数场景 |
伴生对象+lazy | ✔️ | ✔️ | ❌ | ⭐⭐⭐⭐ | 需要控制初始化的场景 |
双重校验锁 | ✔️ | ✔️ | ❌ | ⭐⭐ | 需要高性能的复杂初始化 |
枚举 | ✔️ | ❌ | ✔️ | ⭐⭐⭐ | 需要防止反射攻击的场景 |
Lazy委托 | ✔️ | ✔️ | ❌ | ⭐⭐⭐⭐ | 需要自定义线程安全模式的场景 |
最佳实践建议
- 优先使用对象声明:对于大多数场景,Kotlin的
object
声明是最简单、最安全的选择 - 需要延迟初始化时:使用伴生对象配合
by lazy
- 需要复杂初始化逻辑时:考虑双重校验锁模式
- 在需要防止反射攻击时:考虑枚举实现(但Kotlin中较少需要)
示例:带初始化参数的单例
class Singleton private constructor(val config: String) {companion object {@Volatileprivate var instance: Singleton? = nullfun getInstance(config: String): Singleton {return instance ?: synchronized(this) {instance ?: Singleton(config).also { instance = it }}}}fun doSomething() {println("Doing something with config: $config")}
}// 使用
Singleton.getInstance("myConfig").doSomething()
Kotlin通过语言特性简化了单例模式的实现,使开发者能够更专注于业务逻辑而非样板代码。