创建者模式 -- 单例模式(反射&序列化)
看的视频:https://www.bilibili.com/video/av43896218/?p=286
实现方式:(构造器私有,提供一个外部可以访问的方法(可以提供实例))
1、饿汉式:线程安全,调用效率高, 不能延时加载
2、懒汉式:线程安全,调用效率不高,可以延时加载(要用的时候才加载 )
3、双重锁检测式:“由于JVM底层内部模型原因,偶尔会出现问题,不建议使用”
4、静态内部类式:线程安全,调用效率高,且可以实现延时加载
(上面的四种方式都可以通过反射和反序列化 破坏 单例模式)
5、枚举:线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化
如果单例对象占用资源少,不需要延时加载:
枚举式 优于 饿汉式
如果单例对象占用资源大, 需要延时加载:
静态内部类式 优于 懒汉式
饿汉式:
/*
饿汉式: 最开始就已经把实例给创建好了
*/
public class Singleton01 {
public static Singleton01 instance = new Singleton01(); //一开始就已经创建好了
private Singleton01(){
}
public static Singleton01 getInstance(){
return instance;
}
}
懒汉式:
/*
懒汉式: 用的时候才会初始化实例 效率不高就是因为有synchronized这个关键字
*/
public class Singleton02 {
private static Singleton02 instance = null;
private Singleton02(){
}
public static synchronized Singleton02 getInstance(){
if(instance == null){
instance = new Singleton02();
}
return instance;
}
}
静态内部类:
/*
静态内部类: 只有在主动调用这个类的时候才会加载 外部类加载的时候 静态内部类不会加载
*/
public class Singleton03 {
static class Inner{
private static Singleton03 instance = new Singleton03();
}
private Singleton03(){ }
public static Singleton03 getInstance(){
return Inner.instance;
}
}
枚举:
/*
枚举 天然的可以防止 反射和反序列化
*/
public enum Singleton04 {
INSTANCE; //就表示一个实例 获取的时候直接 Singleton04.INSTANCE
public void method(){
//这里可以写一些方法
}
}
通过反射破坏单例模式:
public class Test01 {
public static void main(String[] args) throws Exception{
Class<?> clazz = Class.forName("com.test.Singleton01");
//获取构造函数:
Constructor c = clazz.getDeclaredConstructor();
c.setAccessible(true); //对于私有属性和方法 设置为允许访问
//通过构造函数 构造实例
Singleton01 singleton001 = (Singleton01)c.newInstance();
Singleton01 singleton002 = (Singleton01)c.newInstance();
System.out.println(singleton001 == singleton002); // false
}
}
如何破坏反射:
public class Singleton01 {
private static boolean flag = false; //标志位
public static Singleton01 instance = new Singleton01(); //一开始就已经创建好了
// 上面的已经调用过一次 这个私有的构造函数了
private Singleton01(){ //反射的时候操作的就是这个私有的构造函数
synchronized (Singleton01.class){
if(flag == false){
flag = true;
}else{ //表示第二次用构造函数进行实例化
throw new RuntimeException("单例模式正在被破坏");
}
}
}
public Singleton01 getInstance(){
return instance;
}
}
在用反射就会报错....
通过反序列化破坏单例模式:
对象序列化:将对象状态转换为字节流的过程,可以将其保存到磁盘文件中或者通过网络发送到任何其他程序中。
反序列化:将字节流转化为对象的过程。
public class Test01 {
public static void main(String[] args) throws Exception{
//序列化 singleton001 Singleton01要实现 Serializable
Singleton01 singleton001 = Singleton01.getInstance();
Singleton01 singleton002 = Singleton01.getInstance();
FileOutputStream fos = new FileOutputStream("d:/a.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(singleton001);
oos.close();
fos.close();
//反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/a.txt"));
Singleton01 singleton003 = (Singleton01)ois.readObject();
System.out.println(singleton001 == singleton002); //true
System.out.println(singleton001 == singleton003); //false
}
}
防止反序列化:
public class Singleton01 implements Serializable {
public static Singleton01 instance = new Singleton01(); //一开始就已经创建好了
private Singleton01(){
}
public static Singleton01 getInstance(){
return instance;
}
//在反序列化的时候 直接调用这个方法 返回instance 而不是返回反序列化后的新对象
private Object readResolve() throws ObjectStreamException {
return instance;
}
}
创建者模式 -- 单例模式(反射&序列化)的更多相关文章
- effective java笔记之单例模式与序列化
单例模式:"一个类有且仅有一个实例,并且自行实例化向整个系统提供." 单例模式实现方式有多种,例如懒汉模式(等用到时候再实例化),饿汉模式(类加载时就实例化)等,这里用饿汉模式方法 ...
- (Builder)创建者模式
定义: 建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示. 适用性: 当流程算法可以固定几个步骤,步骤的算法步骤执行顺序固定,且制造的产品可以唯一确定,这时使用创建 ...
- [设计模式] 3 创建者模式 builder
转载http://blog.csdn.net/wuzhekai1985/article/details/6667467 建造者模式的定义将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不 ...
- Builder创建者模式
http://www.codeproject.com/Articles/42415/Builder-Design-Pattern In Elizabeth's day care center, the ...
- OOAD(面向对象分析和设计)GRASP之创建者模式(Creator)又称生成器模式学习笔记
说OOAD是一门玄学,一点都不为过.又或许是因为我之前一直没有很好的建立面向对象的思想,更有可能是因为练得不够多...总之,一直没能很好理解,哪怕把一本叫做<UML和模式应用>的书翻来覆去 ...
- C#设计模式之五创建者模式(Builder)【创建型】
一.引言 今天我们要讲讲Builder模式,也就是建造者模式,当然也有叫生成器模式的.在现实生活中,我们经常会遇到一些构成比较复杂的物品,比如:电脑,它就是一个复杂的物品,它主要是由CPU.主板.硬 ...
- 创建者模式Builder
创建者模式: 分离对象子组件的单独构造(由Builder来负责)和装配(由Director负责),对象的构造比较复杂时使用 该模式. 类图: Builder 抽象建造者接口,规范各个组成部分的构建. ...
- 设计模式学习总结(五)创建者模式(Builder)
创建者模式,主要针对某些产品有类似的生产步骤,且有需要有先后顺序的进行各个部件的生成. 一.示例展示: 通过学习及总结,以下是我完成的创建者模式的示例: 1.创建产品类:Laptop public c ...
- 复杂UI的组织-创建者模式-uitableview思想
复杂节目的组织-创建者模式-uitableview思想 整体说明,部件规格说明
随机推荐
- python基础之centos7源码安装python3
一.先安装python3所依赖的软件包,非常重要(否则可能会出现python3安装成功,却缺少相应的pip) yum groupinstall "Development tools" ...
- Python3统计gitlab上的代码量
import threading import gitlab import xlwt #获取所有的user def getAllUsers(): usersli = [] client = gitla ...
- 报错: Uncaught TypeError: Cannot read property 'prototype' of undefined(Day_43)
报错原因 引入的js顺序错误,elementUI需要依赖于Vue,调整顺序即可. 调整后
- 面试官问我:如何在 Python 中解析和修改 XML
摘要:我们经常需要解析用不同语言编写的数据.Python提供了许多库来解析或拆分用其他语言编写的数据.在此 Python XML 解析器教程中,您将学习如何使用 Python 解析 XML. 本文分享 ...
- 直击Huawei Mate 40产线背后的华为云IoT智能制造
摘要:数字孪生?在数字世界找到物理世界的设备! 本文分享自华为云社区<[云驻共创]Huawei Mate 40产线直击之华为云IoT智能制造助力工厂数字化转型>,原文作者:启明. Part ...
- Python+Selenium自动化-定位一组元素,单选框、复选框的选中方法
Python+Selenium自动化-定位一组元素,单选框.复选框的选中方法 之前学习了8种定位单个元素的方法,同时webdriver还提供了8种定位一组元素的方法.唯一区别就是在单词elemen ...
- 转载 | Scala 如何避免使用 Null
在 Java 里,null 是一个关键字,不是一个对象,所以对它调用任何方法都是非法的. Scala 的 Option类型 Scala在变量和函数返回值可能不会引用任何值的时候使用 Option 类型 ...
- springboot项目添加swagger2
1.pom中添加swagger依赖 <!-- swagger-ui --> <dependency> <groupId>io.springfox</group ...
- TVM在ARM GPU上优化移动深度学习
TVM在ARM GPU上优化移动深度学习 随着深度学习的巨大成功,将深度神经网络部署到移动设备的需求正在迅速增长.与在台式机平台上所做的类似,在移动设备中使用GPU可以提高推理速度和能源效率.但是,大 ...
- 二、特殊DNS解析
一.DNS轮询 1.为站点 www.tedu.cn 提供DNS轮询解析,三台Web服务器节点的IP地址分别为: 192.168.4.10.192.168.4.20.192.168,4.30 步骤: 虚 ...