iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >kotlin 之单例类详解
  • 389
分享到

kotlin 之单例类详解

kotlinjava 2023-09-02 07:09:39 389人浏览 独家记忆
摘要

object 单例对象的声明: object Model{ var temp = "1" val temp2 = "2" const val temp3 = "3"} 抛出疑问:使

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

--结束END--

本文标题: kotlin 之单例类详解

本文链接: https://www.lsjlt.com/news/390232.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • kotlin 之单例类详解
    object 单例对象的声明: object Model{ var temp = "1" val temp2 = "2" const val temp3 = "3"} 抛出疑问:使...
    99+
    2023-09-02
    kotlin java
  • kotlin之闭包案例详解
    闭包,函数式编程福音 先了解函数式编程(Functional Programming) 概念:它属于“结构化编程”的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。函数式编程...
    99+
    2022-11-12
  • Kotlin 的注解类详解及实例
    Kotlin 的注解类详解及实例注解声明注解是将元数据附加到代码的方法。要声明注解,请将 annotation 修饰符放在类的前面:annotation class Fancy...
    99+
    2023-05-31
    kotlin 注解类
  • Kotlin 泛型详解及简单实例
     Kotlin 泛型详解概述一般类和函数,只能使用具体的类型:要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的约束对代码的限制很大。而OOP的多态采用了一种泛化的机制,在SE 5种,Java引用了泛...
    99+
    2023-05-31
    kotlin 泛型
  • Kotlin this详解及实例
    Kotlin this详解及实例为了表示当前函数的接收者(receiver), 们使用this表达式: 在类的成员函数中,this指向这个类的当前对象实例; 在扩展函数中,或带接收者的函数字面值(function literal) 中,...
    99+
    2023-05-31
    kotlin this his
  • Kotlin-Android之Activity使用详解
    目录Activity中Toast的使用Activity中不使用findViewById()获取控件IDActivity中使用菜单MenuActivity中intent的使用inten...
    99+
    2022-11-12
  • Android Kotlin之Coroutine(协程)详解
    协程是一种并发设计模式,您可以在 Android 平台上使用它来简化异步执行的代码。 在 Android 上,协程有助于管理长时间运行的任务,如果管理不当,这些任务可能会阻塞主线程并导致应用无响应。 协程的优点: 轻量 您可以在单个线程上运...
    99+
    2023-08-16
    android kotlin 协程 Coroutine 异步
  • Kotlin泛型的型变之路演变示例详解
    目录引言协变协变的限制逆变逆变的限制Kotlin型变Kotlin泛型的优化申明处型变reified支持协变的List获取泛型的具体类型reified传入指定Class匿名内部类反射P...
    99+
    2022-12-21
    Kotlin 泛型型变 Kotlin 泛型
  • python 类详解及简单实例
    python 类详解 类 1.类是一种数据结构,可用于创建实例。(一般情况下,类封装了数据和可用于该数据的方法) 2.Python类是可调用的对象,即类对象 3.类通常在模块的顶层进行定义,以便类实例能...
    99+
    2022-06-04
    详解 实例 简单
  • Kotlin基本数据类型详解
    目录1. kotlin 数值型2. kotlin 布尔型3. kotlin 字符型4. kotlin 字符串5. kotlin 可空类型6. kotlin 类型相互转换7. kotl...
    99+
    2022-11-12
  • Kotlin lateinit与by lazy案例详解
    lateinit 和 lazy 是 Kotlin 中的两种不同的延迟初始化的实现 lateinit 只用于变量 var,而 lazy 只用于常量 val lazy 应用于单例模式(...
    99+
    2022-11-12
  • Android Kotlin使用SQLite案例详解
    Kotlin使用SQLite 首先确定我们的目标,SQLite只是一种工具,我们需要掌握就是增删改查就可以,我们真正需要动脑的还是项目中的业务逻辑。我这篇文章写得比较适合新手,没用过...
    99+
    2022-11-12
  • Kotlin 基础语法实例详解
    Kotlin 基础语法实例详解包定义和引入Java一样,在文件开头, 行结束不需要” ; “package com.test.helloimport android.os.Bundle...
    99+
    2023-05-31
    kotlin 基础语法 实例详解
  • kotlin之协程的理解与使用详解
    前言         为什么在kotlin要使用协程呢,这好比去了重庆不吃火锅一样的道理。协程的概念并不陌生,在python也有提及。任何事务...
    99+
    2022-11-12
  • Kotlin协程Dispatchers原理示例详解
    目录前置知识demostartCoroutineCancellableintercepted()函数DefaultScheduler中找dispatch函数Runnable传入Wor...
    99+
    2022-11-13
    Kotlin协程Dispatchers Kotlin Dispatchers
  • Kotlin操作符重载实例详解
    目录算数运算操作符重载复合运算操作符重载一元运算操作符重载比较操作符重载集合和区域的约定迭代运算符重载解构声明总结算数运算操作符重载 在kotlin中我定义一个类 data clas...
    99+
    2022-11-13
  • Kotlin 内联函数详解及实例
    Kotlin 内联函数详解及实例概述在说内联函数之前,先说说函数的调用过程。调用某个函数实际上将程序执行顺序转移到该函数所存放在内存中某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方。这种转移操作要求在转去前要保护现场并记...
    99+
    2023-05-31
    kotlin 内联函数
  • kotlin协程之coroutineScope函数使用详解
    目录正文代码分析正文 public suspend fun <R> coroutineScope(block: suspend CoroutineScope.() -&g...
    99+
    2022-11-13
  • Android Build类的详解及简单实例
    Android Build类的详解及简单实例一、类结构:java.lang.Object? android.os.Build...
    99+
    2023-05-30
    android build类 roi
  • Kotlin定义其他类的实现详解
    目录1.嵌套类2.数据类3.定义数据类的必须满足的条件4.解构声明5.枚举类enum class6.运算符重载1.嵌套类 如果一个类只对另外一个类有作用,那么可以将其嵌入到该类中,使...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作