kotlin

Kotlin中实现单例的几种常见方式

在Kotlin中,实现单例模式比Java更加简洁和优雅。以下是Kotlin中实现单例的几种常见方式:

1. 对象声明(Object Declaration) - 最推荐的方式

kotlin 复制代码
object Singleton {
    init {
        println("Singleton initialized") 
    }
    
    fun doSomething() {
        println("Doing something")
    }
}

// 使用
Singleton.doSomething()

特点

  • 线程安全,由Kotlin保证
  • 懒加载(首次访问时初始化)
  • 简洁明了,推荐使用

2. 伴生对象(Companion Object)实现

kotlin 复制代码
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)

kotlin 复制代码
class Singleton private constructor() {
    companion object {
        @Volatile
        private var instance: Singleton? = null
        
        fun getInstance(): Singleton {
            return instance ?: synchronized(this) {
                instance ?: Singleton().also { instance = it }
            }
        }
    }
    
    fun doSomething() {
        println("Doing something")
    }
}

// 使用
Singleton.getInstance().doSomething()

特点

  • 线程安全
  • 性能优化(只在第一次创建时同步)
  • 适用于需要复杂初始化逻辑的场景

4. 枚举单例(Enum Singleton)

kotlin 复制代码
enum class Singleton {
    INSTANCE;
    
    fun doSomething() {
        println("Doing something")
    }
}

// 使用
Singleton.INSTANCE.doSomething()

特点

  • 线程安全
  • 防止反射攻击
  • 序列化/反序列化安全
  • 但Kotlin中较少使用,因为对象声明通常更简洁

5. 使用Lazy委托属性

kotlin 复制代码
class Singleton private constructor() {
    companion object {
        val instance: Singleton by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
            Singleton()
        }
    }
    
    fun doSomething() {
        println("Doing something")
    }
}

// 使用
Singleton.instance.doSomething()

特点

  • 显式指定线程安全模式
  • 可以自定义初始化逻辑
  • 懒加载

各实现方式对比

实现方式 线程安全 懒加载 防止反射攻击 代码简洁性 适用场景
对象声明 ✔️ ✔️ ⭐⭐⭐⭐⭐ 大多数场景
伴生对象+lazy ✔️ ✔️ ⭐⭐⭐⭐ 需要控制初始化的场景
双重校验锁 ✔️ ✔️ ⭐⭐ 需要高性能的复杂初始化
枚举 ✔️ ✔️ ⭐⭐⭐ 需要防止反射攻击的场景
Lazy委托 ✔️ ✔️ ⭐⭐⭐⭐ 需要自定义线程安全模式的场景

最佳实践建议

  1. 优先使用对象声明 :对于大多数场景,Kotlin的object声明是最简单、最安全的选择
  2. 需要延迟初始化时 :使用伴生对象配合by lazy
  3. 需要复杂初始化逻辑时:考虑双重校验锁模式
  4. 在需要防止反射攻击时:考虑枚举实现(但Kotlin中较少需要)

示例:带初始化参数的单例

kotlin 复制代码
class Singleton private constructor(val config: String) {
    companion object {
        @Volatile
        private var instance: Singleton? = null
        
        fun 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通过语言特性简化了单例模式的实现,使开发者能够更专注于业务逻辑而非样板代码。

相关推荐
孫治AllenSun1 小时前
【DataX】生产环境搭建DataX集群案例
java·开发语言·jvm
c238562 小时前
把 C++ 内存分配拆透:new 与 malloc 的三层血缘
开发语言·c++·算法
moonsims3 小时前
星闪在跨域无人化系统作用
开发语言·php
Iruoyaoxh3 小时前
栈和队列~
java·开发语言
Hrain-AI4 小时前
2026 企业 AI 编程智能体实战:Codex 与 Claude Code
开发语言·人工智能·kotlin
wdfk_prog4 小时前
嵌入式面试真题第 13 题:单硬件 Timer 下的高精度多路软件定时器架构设计
c语言·开发语言·面试·职场和发展·嵌入式
oort1234 小时前
吃上了自家的细糠,还挺丝滑,用起来手感还行,OortCloud发布新版AI编程平台,下载 OortCodex,Token多,免费薅
大数据·开发语言·人工智能·ai编程
slandarer4 小时前
MATLAB | 泰勒图绘制,支持各种角度范围
开发语言·数学建模·matlab·nature·顶刊·泰勒图
mct1235 小时前
c++ iconv 字符utf-8转换gb2312失败
开发语言·c++
zx1154506 小时前
Java 基础复习大纲(详解版)
java·开发语言