创建者模式 -- 单例模式(反射&序列化)
看的视频: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思想 整体说明,部件规格说明
随机推荐
- linux 修改IP, DNS -(转自fighter)
linux下修改IP.DNS.路由命令行设置 ubuntu 版本命令行设置IP cat /etc/network/interfaces # This file describes the networ ...
- 【Web前端HTML5&CSS3】12-字体
笔记来源:尚硅谷Web前端HTML5&CSS3初学者零基础入门全套完整版 目录 字体 1. 字体相关的样式 2. font-family 3. 几种字体 手写体 艺术体 乱码字体 中文字体 4 ...
- 五:.net core(.NET 6)使用Autofac实现依赖注入
Autofac的简单使用: 由于将来可能引用很多包,为了保持统一队形,我们再新建一个类库项目Wsk.Core.Package,当做包的引用集合: 删掉Class1,把Wsk.Core.Wsk.Core ...
- opencv——自适应阈值Canny边缘检测
前言 Canny边缘检测速度很快,OpenCV中经常会用到Canny边缘检测,以前的Demo中使用Canny边缘检测都是自己手动修改高低阈值参数,最近正好要研究点小东西时,就想能不能做个自适应的阈值, ...
- SpringBoot 实现整合log4j2日志
关于日志级别 共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF. ...
- .Net RabbitMQ实战指南——客户端开发
开发中关键的Class和Interface有Channel.Connection.ConnectionFactory.Consumer等,与RabbitMQ相关的开发工作,基本上是围绕Connecti ...
- Python脚本语言写法
Python脚本语言写法 脚本语言的开始行,是指文件中的代码用什么可执行程序去运行它,就这么简单. #!/usr/bin/python是告诉操作系统执行这个脚本的时候,调用/usr/bin下的pyth ...
- Hash源码注释解析
部分代码注释解析: 1 import java.io.IOException; 2 import java.io.InvalidObjectException; 3 import java.io.Se ...
- 从简单示例看对象的创建过程, 为什么双重检查的单例模式,分析Volatile关键字不能少
编译指令 :javac Test.java 反编译指令: javap -v Test 代码 public class ObjectTest { int m = 8; public static voi ...
- fail2ban防护ssh免于暴力破解
一.背景 开放到公网的主机无时无刻不在遭受攻击,其中ssh暴力破解频率最高,会有无数机器不分日夜地搜索公网上的猎物,然后进行弱密码尝试 如果你的公网机器恰巧设的弱密码,估计刚装上系统,没过几小时别人就 ...