第四章:单例模式与final
系列文章目录
文章目录
- 系列文章目录
- 前言
- 一、单例模式
- 二、final 关键字
- 总结
前言
单例模式与final关键字。
一、单例模式
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己在思考和摸索。
| 单例模式 |
|---|
| 采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例并且该类只提供一个取得对象实例的方法 |
| 单例模式有两种方式:1.饿汉式 2.懒汉式 |
| 单例模式的实现 |
|---|
| 1. 构造器私有化,防止直接new |
| 2. 类的内部创建对象并且私有化,为了能够在静态方法中,返回对象,需要将对象修饰为 static |
| 3. 向外暴露一个静态的公共方法:getlnstance |
package com.hspedu.single_;public class SingleTon01 {public static void main(String[] args) {// GirlFriend xh = new GirlFriend("小红");// GirlFriend xb = new GirlFriend("小白");//通过方法可以获取对象GirlFriend instance = GirlFriend.getInstance();System.out.println(instance);GirlFriend instance2 = GirlFriend.getInstance();System.out.println(instance2);System.out.println(instance == instance2);//T//System.out.println(GirlFriend.n1);//...}
}//有一个类, GirlFriend
//只能有一个女朋友
class GirlFriend {private String name;//public static int n1 = 100;//为了能够在静态方法中, 返回 gf 对象, 需要将其修饰为 static//對象, 通常是重量級的對象, 餓漢式可能造成創建了對象, 但是沒有使用.private static GirlFriend gf = new GirlFriend("小红红");//如何保障我们只能创建一个 GirlFriend 对象//步骤[单例模式-饿汉式]//1. 将构造器私有化//2. 在类的内部直接创建对象(该对象是 static)//3. 提供一个公共的 static 方法, 返回 gf 对象private GirlFriend(String name) {System.out.println("構造器被調用.");this.name = name;} public static GirlFriend getInstance() {return gf;}@Overridepublic String toString() {return "GirlFriend{" + "name='" + name + '\'' + '}' ;}}
package com.hspedu.single_;/**
* 演示懶漢式的單例模式
*/public class SingleTon02 {public static void main(String[] args) {//new Cat("大黃");//System.out.println(Cat.n1);Cat instance = Cat.getInstance();System.out.println(instance);//再次調用 getInstanceCat instance2 = Cat.getInstance();System.out.println(instance2);System.out.println(instance == instance2);//T}
} //希望在程序運行過程中, 只能創建一個 Cat 對象
//使用單例模式
class Cat {private String name;public static int n1 = 999;private static Cat cat ; //默認是 null//步驟//1.仍然構造器私有化//2.定義一個 static 靜態屬性對象//3.提供一個 public 的 static 方法, 可以返回一個 Cat 對象//4.懶漢式, 只有當用戶使用 getInstance 時, 才返回 cat 對象, 後面再次調用時, 會返回上次創建的 cat 對象// 從而保證了單例private Cat(String name) {System.out.println("構造器調用...");this.name = name;} public static Cat getInstance() {if(cat == null) {//如果還沒有創建 cat 對象cat = new Cat("小可愛");} return cat;} @Overridepublic String toString() {return "Cat{" +"name='" + name + '\'' +'}';}
}
| 饿汉式vs懒汉式 |
|---|
| 二者最主要的区别在于创建对象的时机不同:饿汉式是在类加载就创建了对象实例而懒汉式是在使用时才创建 |
| 饿汉式不存在线程安全问题,懒汉式存在线程安全题,(后面学习线程后,会完善一把) |
| 饿汉式存在浪费资源的可能。因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了,懒汉式是使用时才创建,就不存在这个问题 |
| 在我们javaSE标准类中,java.lang.Runtime就是经典的单例模式 |
二、final 关键字
final:最后的,最终的。可以修饰类、属性、方法和局部变量。
| final用法 |
|---|
| 1. 当不希望类被继承时,可以用final修饰 |
| 2. 当不希望父类的某个方法被子类覆盖/重写(override)时,可以用final关键字修饰 |
| 3. 当不希望类的的某个属性的值被修改,可以用final修饰 |
| 4. 当不希望某个局部变量[方法体内的形参]被修改,可以使用final修饰 |
package com.hspedu.final_;public class Final01 {public static void main(String[] args) {E e = new E();//e.TAX_RATE = 0.09;}
}
//如果我们要求 A 类不能被其他类继承
//可以使用 final 修饰 A 类
final class A { }//class B extends A {}
class C {//如果我们要求 hi 不能被子类重写//可以使用 final 修饰 hi 方法public final void hi() {}
} class D extends C {// @Override// public void hi() {// System.out.println("重写了 C 类的 hi 方法..");// }
} //当不希望类的的某个属性的值被修改,可以用 final 修饰
class E {public final double TAX_RATE = 0.08;//常量
} //当不希望某个局部变量被修改, 可以使用 final 修饰
class F {public void cry() {//这时, NUM 也称为 局部常量final double NUM = 0.01;//NUM = 0.9;System.out.println("NUM=" + NUM);}
}
| final使用细则part1 |
|---|
| final修饰的属性又叫常量,一般用XX_XX_XX来命名 |
| final修饰的属性在定义时,必须赋初值并且以后不能再修改,赋值可以在如下位置之一【选择一个位置赋初值即可]: 定义时/在构造器中/在代码块中 |
| 如果final修饰的属性是静态的,则初始化的位置只能是:定义时/在静态代码块不能在构造器中赋值 |
| final类不能继承,但是可以实例化对象 |
| 如果类不是final类,但是含有final方法, 则该方法虽然不能重写,但是可以被继承 |
package com.hspedu.final_;public class FinalDetail01 {public static void main(String[] args) {CC cc = new CC();new EE().cal();}
} class AA {/*1. 定义时: 如 public final double TAX_RATE=0.08;2. 在构造器中3. 在代码块中*/public final double TAX_RATE = 0.08;//1.定义时赋值public final double TAX_RATE2 ;public final double TAX_RATE3 ;public AA() {//构造器中赋值TAX_RATE2 = 1.1;} {//在代码块赋值TAX_RATE3 = 8.8;}
} class BB {/*如果 final 修饰的属性是静态的, 则初始化的位置只能是1 定义时 2 在静态代码块 不能在构造器中赋值。*/public static final double TAX_RATE = 99.9;public static final double TAX_RATE2 ;static {TAX_RATE2 = 3.3;}
} //final 类不能继承, 但是可以实例化对象
final class CC { }//如果类不是 final 类, 但是含有 final 方法, 则该方法虽然不能重写, 但是可以被继承
//即, 仍然遵守继承的机制.
class DD {public final void cal() {System.out.println("cal()方法");}
} class EE extends DD { }
| final使用细则part2 |
|---|
| 一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法 |
| final不能修饰构造方法(即构造器) |
| final和static往往搭配使用,效率更高,不会导致类的加载,底层编译器做了优化处理 |
| 包装类(Integer,Double,Float,Boolean等都是final),String也是final类 |
package com.hspedu.final_;public class FinalDetail02 {public static void main(String[] args) {System.out.println(BBB.num);//包装类,String 是 final 类, 不能被继承}
} //final 和 static 往往搭配使用, 效率更高, 不会导致类加载.底层编译器做了优化处理
class BBB {public final static int num = 10000;static {System.out.println("BBB 静态代码块被执行");}
}final class AAA{//一般来说, 如果一个类已经是 final 类了, 就没有必要再将方法修饰成 final 方法//public final void cry() {}}
总结
单例模式是非常通用的类设计模式,final关键字经常与static关键字搭配使用。
相关文章:
第四章:单例模式与final
系列文章目录 文章目录 系列文章目录前言一、单例模式二、final 关键字总结 前言 单例模式与final关键字。 一、单例模式 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。就像是经典的棋谱,不同的棋局,我…...
深入Android S(12.0) 探索 Android Framework 之 SystemServer 进程启动详解
深入学习 Android Framework 第三:深入Android S(12.0) 探索 Android Framework 之 SystemServer 进程启动详解 文章目录 深入学习 Android Framework前言一、Android 系统的启动流程1. 流程图2. 启动流程概述 二、源码详解1. 时序图2. 源代码1、ZygoteInit # main…...
搜维尔科技:【软件篇】TechViz是一款专为工程设计的专业级3D可视化软件
在沉浸式房间内深入研究您自己的 3D 数据 沉浸式房间是一个交互式虚拟现实空间,其中每个表面(墙壁、地板和天花板)都充当投影屏幕,创造高度沉浸式的体验。这就像您的 3D 模型有一个窗口,您可以在其中从不同角度走动、…...
android Handler
一、Handler的作用 1、Handler的作用是在andorid中实现线程间的通信。我们常说的说的,子线程处理逻辑,主线程更新UI是上述情况的一个子集。 二、源码分析 1、Handler源码 源码地址:http://androidxref.com/7.1.1_r6/xref/frameworks/base/co…...
【Ubuntu·系统·的Linux环境变量配置方法最全】
文章目录 概要读取环境变量的方法小技巧 概要 在Linux环境中,配置环境变量是一种常见的操作,用于指定系统或用户环境中可执行程序的搜索路径。 读取环境变量的方法 在Linux中,可以使用以下两个命令来读取环境变量: export 命令…...
Django之模板层
【1】模板之变量 在Django模板中要想使用变量关键是使用点语法。 获取值的语法是:{{ 变量名 }} Python中所有的数据类型包括函数,类等都可以调用 【2】模板之过滤器 过滤器语法 {{ obj | filter_name:param }} obj:变量名字&…...
社区论坛小程序系统源码+自定义设置+活动奖励 自带流量主 带完整的搭建教程
大家好啊,又到了罗峰来给大家分享好用的源码的时间了。今天罗峰要给大家分享的是一款社区论坛小程序系统。社区论坛已经成为人们交流、学习、分享的重要平台。然而,传统的社区论坛往往功能单一、缺乏个性化设置,无法满足用户多样化的需求。而…...
2023亚太杯数学建模C题思路解析
文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料5 最后 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 2023年第十三…...
acme在同一台服务器上设置多个Ali_key实现自动ssl申请和续期
在同一台服务器上设置多个Ali_key,您可以按照以下步骤进行操作: 首先,确保您已经安装了acme.sh工具。如果没有安装,请先安装acme.sh,您可以使用以下命令安装acme.sh: curl https://get.acme.sh | sh安装完…...
乐观锁与悲观锁
乐观锁 乐观锁是一种并发控制的机制,其核心思想是假设多个事务之间的冲突是不太可能发生的,因此在事务处理之前不会加锁,而是在事务提交的时候再检查是否有冲突。如果发现冲突,就会回滚事务,重新尝试。 实现乐观锁的方…...
【算法】堆排序
算法-堆排序 前置知识 堆(即将更新) 思路 我们现在有一个序列,怎么对它排序? 这是一个非常经典的问题,这里我们使用一个借助数据结构的算法——堆排序解决。 这里有一个序列,要对它升序排序 4 7 3 6 5 …...
51单片机应用从零开始(三)
51单片机应用从零开始(一)-CSDN博客 51单片机应用从零开始(二)-CSDN博客 详解 KEIL C51 软件的使用建立工程-CSDN博客 详解 KEIL C51 软件的使用设置工程编绎与连接程序-CSDN博客 目录 1. 用单片机控制第一个灯亮 2. 认识单片…...
如何在 Nginx Proxy Manager(NPM)上部署静态网站
前言 众所周知,我们在之前介绍过 Nginx Proxy Manager(以下简称 NPM) 这个反向代理的神器,对于一些 Docker 搭建的 Web 项目,NPM 能够很轻松地给他们做反向代理。 然而对于一些静态网站,小伙伴们可能不知道怎么用 NP…...
http的几种方法
http的几种方法在 rfc2616 中进行了定义: https://www.rfc-editor.org/rfc/rfc2616.html#page-51 HEAD方法:HEAD方法和GET方法相同,只不过服务端只返回头,不返回消息体。GET方法:用于获取资源POST方法:用于…...
var、let、const关键字的特性,以及let、const暂时性死区的作用
var、let和const都是JavaScript中的关键字,用于声明变量。 var关键字声明的变量是函数作用域或全局作用域的,它在整个函数或全局范围内都是可用的。var没有块级作用域。 let关键字声明的变量是块级作用域的,它只在包含它的代码块中可用。le…...
IDEA 高分辨率卡顿优化
VM设置优化 -Dsun.java2d.uiScale.enabledfalse 增加该条设置,关闭高分切换 https://intellij-support.jetbrains.com/hc/en-us/articles/115001260010-Troubleshooting-IDE-scaling-DPI-issues-on-Windowsintellij-support.jetbrains.com/hc/en-us/articles/1…...
【AIGC】一起学习prompt提示词(4/4)【经典】【15种提示词技巧】
写的时候并没有设计好,要做多少期,还是有始有终的比较好,为了方便阅读,我把之前的3期,改下名字,放到这里。 【AIGC】一起学习prompt提示词(1/4) 内容摘要:提示词是什么…...
Linux实战一天一个小指令--《文件管理/文件查找》
阿丹: 作为一个java程序员进行实战开发不接触linux操作系统基本上是不可能的,所以这个专题就出现了,本文章重点解决大家关于文件管理以及文件查找查看的疑惑。我将采用语法基础用法并在下面进行高级语法的总结使用,方便大家学习和…...
CocosCreator3.8神秘面纱 CocosCreator 项目结构说明及编辑器的简单使用
我们通过Dashboard 创建一个2d项目,来演示CocosCreator 的项目结构。 等待创建完成后,会得到以下项目工程: 一、assets文件夹 assets文件夹:为资源目录,用来存储所有的本地资源,如各种图片,脚本…...
JJJ:python学习笔记
p4 没有编译的过程 源码和输入得到输出 静态语言:编译型 脚本语言:解释型 p5 又叫做胶水语言 p7 p8 p10...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
