文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

kotlin 之单例类详解

2023-09-02 07:49

关注

object

单例对象的声明:

object  Model{    var temp = "1"    val temp2 = "2"    const val temp3 = "3"}

抛出疑问:使用object修饰的类,是哪种类型的单例模式

这里我们先回顾一下java六种单例模式

1. 饿汉式
public class HungryMan {    private HungryMan(){}    private static HungryMan hungryMan = new HungryMan();    public static HungryMan getInstance(){        return hungryMan;    }}

优点:简单方便,线程安全

缺点:无论是否用到,都会进行实例化,而且在类加载时就会实例化

2. 懒汉式
public class LazyMan {    private static LazyMan lazyMan = null;    private LazyMan() {    }    public static LazyMan getInstatce() {        if (lazyMan == null) {            lazyMan = new LazyMan();        }        return lazyMan;    }}

优点:只有在使用时才会生成对象,能够减少内存开销

缺点:线程不安全,只能在单线程中使用,多个线程访问时,会产生多个对象,

3.懒汉式同步锁
public class LazyMan {    private static volatile LazyMan lazyMan = null;    private LazyMan() {    }    public static LazyMan getInstatce() {        synchronized (LazyMan.class){            if (lazyMan == null) {                lazyMan = new LazyMan();            }        }        return lazyMan;    }}

优点:支持多线程

缺点:每次都会有一个加锁以及释放锁的操作,效率低,可以通过反射破坏单例模式。

4.DCL双检测锁
public class LazyMan {    private static volatile LazyMan lazyMan = null;    private LazyMan() {    }    public static LazyMan getInstatce() {        if(lazyMan == null){            synchronized (LazyMan.class){                if (lazyMan == null) {                    lazyMan = new LazyMan();                }            }        }        return lazyMan;    }}

这里引入一下解释一下DCL双检测锁机制:

DCL双检测锁机制: 用DCL双检测锁机制为什么要用valoatile修饰,因为lazyMan=new LazyMan(), 并非是一个原子操作。事实上在JVM中大概做了3件事。

lazyMan分配内存,

调用构造器来初始化成员变量

lazyMan对象指向分配的内存空间。 但是JVM的即时编译器中存在指令重排序的优化,也就是说上面的第二步,第三步顺序是不 确定的一旦2,3,顺序乱了,这个是有一个线程调用了方法,结果虽然是非null,但是未初 始化,所以直接报错。

优点:效率高,线程安全

缺点:代码复杂,可以通过反射破坏单例

5.静态内部类
public class Singleton {     private Singleton() {}     private static class SingletonInstance {//私有静态内部类        private static final Singleton INSTANCE = new Singleton();    }     public static Singleton getInstance() {        return SingletonInstance.INSTANCE;    }}

优点:类的静态属性只有在第一次加载类的时候初始化,所以线程安全

缺点:代码变得复杂,apk文件增大

6. 枚举单例
public enum SingleTon {    SINGLE_TON;    private String field;    public String getField() {        return field;    }    public void setField(String field) {        this.field = field;    }}

优点:线程安全,不用担心反射破话单例模式

缺点:枚举类占用内存多

解析:object 单例类是什么类型的单例

这里我们直接将kotlin代码转为Java 代码进行查看。

kotlin代码如下

转为Java之后

我们可以看到,该Model类转为Java代码之后,它是一个饿汉式单例。所以使用object的类采用的是饿汉式单例。

companion object伴生对象出现的单例是哪种类型的单例

kotlin代码如下

class  Model{    companion object{        val text = ApiWrapper("11")    }}class ApiWrapper (val api : String){     fun s() {          }}

java代码如下

public final class Model {   @NotNull   private static final ApiWrapper text = new ApiWrapper("11");   @NotNull   public static final Model.Companion Companion = new Model.Companion((DefaultConstructorMarker)null);   public static final class Companion {      @NotNull      public final ApiWrapper getText() {         return Model.text;      }      private Companion() {      }      public Companion(DefaultConstructorMarker $constructor_marker) {         this();      }   }}

可以看的出来,如果直接对text赋值,那么就相当于是一个饿汉式加载

但是如果我们对text进行by lazy延迟赋值,那么会是什么样子呢。

public final class Model {   @NotNull   private static final Lazy text$delegate;   @NotNull   public static final Model.Companion Companion = new Model.Companion((DefaultConstructorMarker)null);   static {      text$delegate = LazyKt.lazy((Function0)null.INSTANCE);   }   public static final class Companion {      @NotNull      public final ApiWrapper getText() {         Lazy var1 = Model.text$delegate;         Model.Companion var2 = Model.Companion;         Object var3 = null;         return (ApiWrapper)var1.getValue();      }      private Companion() {      }      public Companion(DefaultConstructorMarker $constructor_marker) {         this();      }   }}

可以看出,此时变成了懒汉式同步单例

至于为什么是同步单例,这里需要大家去看一下LazyKt.lazy()方法

来源地址:https://blog.csdn.net/weixin_44710164/article/details/127889022

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯