【设计模式】Kotlin 与 Java 中的单例

文章介绍了单例模式的概念和在Java中的常见实现,包括饿汉式和懒汉式,重点讲解了双重校验锁的实现以确保线程安全。同时,对比了Kotlin中使用object关键字创建单例的简便方式以及可能的内存泄漏问题,并展示了Kotlin懒汉式的写法。强调了新语言虽简化代码,但理解底层逻辑的重要性。
摘要由CSDN通过智能技术生成

单例模式

单例模式是一个很常见的设计模式,尤其是在 Java 中应用非常广泛。单例模式的定义是保证一个类仅有一个实例,并提供一个访问它的全局访问点。

Java 中的单例模式

Java 中存在多种单例模式的实现方案,最经典的包括:

  • 懒汉式

  • 饿汉式

  • 双重校验锁

饿汉式 / 静态单例

Java 中懒汉式单例如其名一样,“饿” 体现在不管单例对象是否存在,都直接进行初始化:

public final class SingleManager {
    @NotNull
    public static final SingleManager INSTANCE = new SingleManager();

    private SingleManager() {}

    public static SingleManager getInstance() {
        return INSTANCE;
    }
}

实际上,这也是静态单例。

懒汉式 / 延迟初始化

Java 中的懒汉式核心特点在于“懒” ,它不像饿汉式,无论 INSTANCE 是否已经存在值,都进行初始化;而是在调用 get 方法时,检查引用对象是否为空,如果为空再去初始化:

public final class SingleManager {
    public static SingleManager INSTANCE;

    private SingleManager() {}

    public static SingleManager getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new SingleManager();
        } 
        return INSTANCE;
    }
}

双重校验锁

public final class SingleManager {
    // volatile 防止指令重排,确保原子操作的顺序性
    public volatile static SingleManager INSTANCE;

    private SingleManager() {}

    public static SingleManager getInstance() {
        // 第一次判空,减少进入同步锁的次数,提高效率
        if (INSTANCE == null) {
            // 确保同步
            synchronized (SingleManager.class) {
                // 确保加锁后,引用仍是空的
                if (INSTANCE == null) {
                    INSTANCE = new SingleManager();
                }
            }
        }
        return INSTANCE;
    }
}

Kotlin 中的单例模式

object 关键字

Kotlin 提供了比 Java 更方便的语法糖 object 关键字,能够更方便地实现单例模式:

object SingleManager {
    fun main() {}
}

使用:

// used in kotlin
SingleManager.main()
// used in java
SingleManager.Companion.main();

如果要在 Java 中的使用方式与 Kotlin 使用方式一致,可以在方法上添加 @JvmStatic 注解:

object SingleManager {
    @JvmStatic
    fun main() {}
}

// used in java
SingleManager.main();

object 关键字实现的单例,编译为 Java 字节码的实现是:

public final class SingleManager {
   @NotNull
   public static final SingleManager INSTANCE;

   public final void main() {
   }

   private SingleManager() {
   }

   static {
      SingleManager var0 = new SingleManager();
      INSTANCE = var0;
   }
}

这是一种标准的 Java 静态单例实现。

Kotlin 懒汉式

在一些特殊的情况,例如你的单例对象要保存一些不适合放在静态类中的引用,那么使用 object 就不是合适的方案了,例如,Android 中的上下文 Context 、View 都不适合在静态类中进行引用,IDE 也会提醒你这样会造成内存泄漏:

一种好的解决方案是在 Kotlin 中使用懒汉式的写法:

class SingleManager {
    companion object {
        private var instance: SingleManager? = null

        fun getInstance(): SingleManager {
            if (instance == null) {
                instance = SingleManager()
            }
            return instance!!
        }
    }

    var view: View? = null
}

但是这样仍然会提醒你不要引用:

但如果引用的对象是你自定义的 View :

class BaseView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : FrameLayout(context, attrs)

在 kotlin 中懒汉式是不会提示你的:

可以看出,使用 object 关键字,仍然会飘黄,提醒你可能存在内存泄漏。

本质上来说,没有提示实际上也是存在内存泄漏的隐患的。 虽然可以骗过 IDE 但不应该欺骗自己。

写在最后

Kotlin 作为一门更新的 JVM 语言,它提供了很多语法糖突破了 Java 的一些固定写法,有些设计模式已经不再适合新的语言(例如 Builder 模式在 Kotlin 中很少会出现了)。虽然新语言简化了代码的复杂度、简化了写法,但不能简化知识点,例如,使用 Kotlin 需要一个线程安全的单例,仍然可以使用双重校验锁的写法。本质上还是要搞清楚底层逻辑。

作者:自动化BUG制造器
链接:https://juejin.cn/post/7200708877389070395

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。

在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集
在这里插入图片描述
二、源码解析合集

在这里插入图片描述
三、开源框架合集

在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值