Java学习之单例设计模式

news2025/1/18 3:23:34

目录

设计模式

单例模式

一、饿汉式

二、懒汉式

三、饿汉式VS懒汉式

总结


设计模式

1.静态方法和属性的经典使用

2.设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格以及解决问题的思考方式。就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和摸索

单例模式

类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法

一、饿汉式

一般情况下创建对象的代码

package com.hspedu.single_;

public class SingleTon01 {
    public static void main(String[] args) {
        GirlFriend gf1 = new GirlFriend("小红");
        GirlFriend gf2 = new GirlFriend("小黄");
    }
}
class GirlFriend {
    private String name;

    public GirlFriend(String name) {
        this.name = name;
    }
}

构造器私有化,构造器私有化之后无法在main方法内创建新对象 

private GirlFriend(String name) {
        this.name = name;
    }

 解决方法

1.构造器私有化

2.在类中创建新对象

3.创建public static 方法,在方法中return创建的新对象

4.在main方法中通过类名.方法名调用上述方法

package com.hspedu.single_;

public class SingleTon01 {
    public static void main(String[] args) {
//        GirlFriend gf1 = new GirlFriend("小红");
//        GirlFriend gf2 = new GirlFriend("小黄");

        //调用静态方法,获取对象,接收返回的对象
        //调用静态方法,导致类加载,类加载只会进行一次
        GirlFriend gf1 = GirlFriend.getInstance();
        //输出对象,格式 全类名 + @ + 哈希值的十六进制
        System.out.println(gf1);
        System.out.println(gf1);

     

    }
}
//有一个类,GirlFriend
//只能有一个女朋友
class GirlFriend {
    private String name;
   

    //如何保障我们只能创建一个GirlFriend对象
    //单例模式-饿汉式
    //1.构造器私有化(防止new对象)
    //2.类的内部创建对象(static对象)
    //3.提供一个public static 方法,返回上述创建的对象

    //因为要在static方法中return,所以必须是static修饰
    private static final GirlFriend gf = new GirlFriend("小红");

    private GirlFriend(String name) {
        this.name = name;
    }

    //必须是static方法,因为构造器私有化,无法通过对象名.类名调用,只能通过类名.方法名调用
    public static GirlFriend getInstance(){
        return gf;
    }

    @Override
    public String toString() {
        return "GirlFriend{" +
                "name='" + name + '\'' +
                '}';
    }
}

饿汉式的名称由来:在类加载的时候就已经创建好了对象,不论调用不调用,都已经创建好了

eg:

package com.hspedu.single_;

public class SingleTon01 {
    public static void main(String[] args) {


        System.out.println(GirlFriend.n1);

    }
}
//有一个类,GirlFriend
//只能有一个女朋友
class GirlFriend {
    private String name;
    public static int n1 = 100;

    //如何保障我们只能创建一个GirlFriend对象
    //单例模式-饿汉式
    //1.构造器私有化(防止new对象)
    //2.类的内部创建对象(static对象)
    //3.提供一个public static 方法,返回上述创建的对象

    //因为要在static方法中return,所以必须是static修饰
    private static final GirlFriend gf = new GirlFriend("小红");

    private GirlFriend(String name) {
        System.out.println("构造器被调用");
        this.name = name;
    }
    //必须是static方法,因为构造器私有化,无法通过对象名.类名调用,只能通过类名.方法名调用
    public static GirlFriend getInstance(){
        return gf;
    }

    @Override
    public String toString() {
        return "GirlFriend{" +
                "name='" + name + '\'' +
                '}';
    }
}

  

上述代码调用了静态变量n1,完成了类加载,所以对象gf也被创建了 

二、懒汉式

等用到的时候再创建对象

package com.hspedu.single_;

public class SingleTon02 {
    public static void main(String[] args) {
        //调用静态方法,cat的默认值为null
        //执行 cat = new Cat("圆圆");
        Cat instance = Cat.getInstance();
        System.out.println(instance);

        //再次调用静态方法getInstance()
        //经过上述操作,对象cat 已经 ≠ null
        //不会再创建新对象,还是输出“圆圆”
        Cat instance1 = Cat.getInstance();
        System.out.println(instance1);

    }
}
class Cat{
    private String name;
    private static Cat cat;//对象为引用
    //构造器私有化
    //定义一个静态属性:对象
    //提供一个public static 方法,返回对象
    private Cat(String name) {
        System.out.println("构造器被调用");
        this.name = name;
    }

    public static Cat getInstance(){
        if(cat == null){
            cat = new Cat("圆圆");
        }
        return cat;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                '}';
    }
}

只有一个对象实例,第二次调用的时候输出的还是第一次创建的对象实例,因此,构造器也只会调用一次

三、饿汉式VS懒汉式

二者最主要的区别在于

1.创建对象的时机不同: 饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建

2.饿汉式不存在线程安全问题,懒汉式存在线程安全问题。(线程还没学到)

3.饿汉式存在浪费资源的可能。因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了,懒汉式是使用时才创建,就不存在这个问题。


4.在我们javaSE标准类中,java.lang.Runtime就是经典的单例模式

代码

public class Runtime {
    //私有的static属性:变量;在类加载的时候就会创建,饿汉式
    private static final Runtime currentRuntime = new Runtime();

    private static Version version;
    
    //public static 方法 返回currentRuntime
    public static Runtime getRuntime() {
        return currentRuntime;
    }
    //构造器私有化
    private Runtime() {}
}

总结

1.单例模式的两种实现方式(1) 饿汉式(2) 懒汉式

2.饿汉式的问题:在类加载时候就创建,可能存在资源浪费问题

3.懒汉式的问题: 线程安全问题,后面学了线程后,再进行完善

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/158642.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

连接查询之外连接(左外链接和右外连接)

内连接: 假设A表和B表进行连接查询,使用内连接的话,凡是A表和B表能够匹配上的记录被查询出来,这就是内连接。A、B两张表没有主副之分,两张表是平等的。 外连接: 假设A表和B表进行连接查询,使用…

对于html中div标签height属性的个人理解

对于没有系统学习过css的程序员来说,在编写css样式的时候,div的height属性值确实是个玄学的东西,我也感觉css确实挺玄学的,本文将介绍我对div标签height属性的个人理解,如有问题请指正。 在html中,div标签属…

xilinx srio ip学习笔记之srio example

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 xilinx srio ip学习笔记之srio example前言IP的配置例程前言 前面对SRIO的理论有了初步的理解,现在急需要通过理解例程并且修改例程来建立自信心了。 学东西确实…

Java版本TransH代码的学习

主要讲和TransE代码的区别,TransE文章的链接 Java版本TransE代码的学习 关于范数的概念 什么是0范数、1范数、2范数?区别又是什么 初始化向量 初始化关系平面的向量Wr,初始化向量relation_vec,初始化节点向量entity_vec Wr_vec new doub…

富豪酒店集团全新体验「METAGREEN」上线!边玩边赚,了解可持续发展!

富豪酒店集团推出 MetaGreen 以提高大众对可持续发展的认识,并创造一个多元化的绿色生态系统。 体验将包涵盖数个独特的互动地标,包括环保富豪酒店、大华银行艺术空间、恒生银行元宇宙分行,以及 citysuper、LOG-ON 和 The Mills 等零售商。 …

擎创技术流 | ClickHouse实用工具—ckman教程(9)

哈喽~大家好,时间倏然,上一次ckman分享还是在2022,这一期分享就已经是2023了。由于前段时间小编“成功加入羊群”,导致拖更一周,实在抱歉。希望新的一年大家都可以身体健健康康,事业红红火火,生…

Clarifying Question领域最常见的三个数据集

文章目录Qulacqulac.json:qulac_hist012_dict.tar.gz:MIMICSClariQConvAI3 Data ChallengeStage1: initial datasetStage2: human-in-the-loopClariQ DatasetFile Formattrain.tsv and dev.tsvtest.tsvquestion_bank.tsvdev_synthetic.pkl.tar.gz & train_synthetic.pkl.ta…

【进阶】Spring核心思想及其项目创建

努力经营当下,直至未来明朗! 文章目录一、Spring核心思想1. 容器2. IoC3. SpringIoC4. DI概念说明二、Spring的创建和使用1. 创建Spring项目3. Maven项目导入jar包和设置国内源的方法:2. Spring对象的存储/存储Bean对象3. 从Spring中读取到Be…

Electron自定义协议Protocol对web网站做数据交互,使用SSE实时数据推送到网站

(防盗镇楼)本文地址:https://blog.csdn.net/cbaili/article/details/128651549 前言 最近在撸VUE,想要实现一份代码既能构建Web又能构建Electron应用 并且能够判断环境是浏览器还是Electron,随后在Electron中做一些特定的事情 以往的Electron通信依靠IPC通信完成,但是发布到…

模板(template)包含与继承

Django 模板查找机制: Django 查找模板的过程是在每个 app 的 templates 文件夹中找(而不只是当前 app 中的代码只在当前的 app 的 templates 文件夹中找)。各个 app 的 templates 形成一个文件夹列表,Django 遍历这个列表&#x…

超详细的Socket通信原理和实例讲解

我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket&am…

【算法篇-排序】八大排序

十大排序0.常见排序1. 插入排序(直接插入排序和希尔排序)1.1直接插入排序1.2希尔排序(缩小增量排序)2.选择排序2.1选择排序2. 2堆排序3.交换排序3.1 冒泡排序3.2快速排序3.2.1hoare版本快排3.2.2挖坑法3.2.3前后指针法3.3.4 快排的…

【Linux】在Linux上写一个进度条小程序

👑作者主页:安 度 因 🏠学习社区:安度因的学习社区 📖专栏链接:Linux 文章目录一、前言二、理解 \r 与 \n三、行缓冲1、提出问题2、认识行缓冲3、解答与拓展4、倒计时四、进度条五、结语如果无聊的话&#…

2023/1/12总结

今天学习了图的割点与桥的算法 图的割点以及桥 图的割点:割点是指在无向连通图中,某点和该点连接的边去掉以后图便不再连通 在上面的图片中(上面是一个有向图,我们当作无向图即可)我们知道当我们去掉A点之后&#xf…

进阶必看 | 6个让Revit建模起飞的习惯,高效就靠它

大家好,这里是建模助手。 相信各位都知道,建模助手一向以来都追求更高,更快,更强。但是有些问题,不是插件本身能解决的事情,而是项目本身的问题。 一般来说,当Revit项目模型大于150MB时&#…

Linux安装sonarqube(含各种错误处理)

目录 1.下载安装 2.错误处理 2.1.JDK版本不适配 2.2.can not run elasticsearch as root 1.下载安装 下载地址: Download | SonarQube | Sonar (下载页面向下拉)选择稳定版本下载。 解压后启动脚本在: bin/{对应操作系统}…

【dp】买卖股票的最佳时机系列题目

文章目录121. 买卖股票的最佳时机122. 买卖股票的最佳时机 II309. 最佳买卖股票时机含冷冻期123. 买卖股票的最佳时机 III188. 买卖股票的最佳时机 IV121. 买卖股票的最佳时机 本题的重点是:只能在前面某一天买入,后面某一天卖出。要不就是不买入&#x…

外贸业务员怎样能提高自己的工作能力?

关于外贸业务员提高自己的工作能力,米贸搜整理如下,希望可以帮助到你:1.树立一个好的目标,并坚定不移地朝着这个目标努力。这个问题,无论你是新手还是有经验的外贸业务员,相信每个外贸业务员都或多或少的思…

K_A11_004 基于STM32等单片机采集热敏传感参数串口与OLED0.96双显示

K_A11_004 基于STM32等单片机采集热敏传感参数串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明IIC地址/采集通道选择/时序对应程序:四、部分代码说明1、接线说明1.1、STC89C52RC热敏传感模块1.2、STM32F103C8T6热敏传感模块五、基础知识学习与相关资料下…

NCS8823替代方案|CS5260Typec转VGA可替代NCS8823|低BOM成本替代NCS8823设计

NCS8823替代方案|CS5260Typec转VGA可替代NCS8823|低BOM成本替代NCS8823设计 NCS8823是一款低功耗、DisplayPort信号至VGA转换器,通过USB Type-C连接器。它是 适用于USB Type-C至VGA转换器,适配器、对接设备。此设备结合了基于USB Type-C的 DisplayPort接收器和VGA…