版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37776094/article/details/89632665
项目源码已提交github:https://github.com/ckl001/designPattem_java
创建型
单例模式
1.饿汉模式
2.懒汉模式
3.内部类模式
4.枚举模式
破坏单例模式
1.序列化
2.反射
package com.Ljava.design.pattem.creational.singleton;
/**
* @Auther 20173
* @Date 2019-4-8 11:48
* @Des 单例:枚举 推荐使用
**/
public enum EnumInstance {
INSTANCE{
protected void prinTest() {
System.out.println("print test!");
}
};
protected abstract void prinTest();
public static EnumInstance getInstance(){
return INSTANCE;
}
public Object data;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}}
package com.Ljava.design.pattem.creational.singleton;
import java.io.Serializable;
/**
* @Auther 20173
* @Date 2019-4-8 11:48
* @Des 单例:饿汉模式
**/
public class HungrySingleton implements Serializable {
private final static HungrySingleton hungrySingleton;
static {
hungrySingleton = new HungrySingleton();
}
//防止反射破坏单例模式
private HungrySingleton(){
if(hungrySingleton != null){
throw new RuntimeException("单例模式禁止反射调用!");
}
}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
// 解决对象反序列化;
// 反序列化的时候会进行浅拷贝则返回的对象是新的对象;
// Singleton中定义readResolve方法,并在该方法中指定要返回的对象的生成策略,就可以防止单例被破坏。
private Object readResolve(){
System.out.println("调用了readResolve方法!");
return hungrySingleton;
}
}
package com.Ljava.design.pattem.creational.singleton;
/**
* @Auther 20173
* @Date 2019-4-8 14:06
* @Des 单例: 懒汉模式--双重锁
**/
public class LazyDoubleCheckSingleton {
// volatile 防止指令重排,内存可见性
private volatile static LazyDoubleCheckSingleton lazyDoubleCheckSingleton = null;
public LazyDoubleCheckSingleton() {
}
public static LazyDoubleCheckSingleton getInstance(){
if(lazyDoubleCheckSingleton == null){
synchronized (LazyDoubleCheckSingleton.class){
if(lazyDoubleCheckSingleton == null){
// 1.分配内存给这个对象
// 2.初始化这个对象
// 3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址
// 指令重排:第二步跟第三步的顺序调换
lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton();
}
}
}
return lazyDoubleCheckSingleton;
}
}
package com.Ljava.design.pattem.creational.singleton;
/**
* @Auther 20173
* @Date 2019-4-8 14:34
* @Des 单例模式: 静态内部类
**/
public class StaticInnerClassSingleton {
//内部类
private static class InnerClass{
private static StaticInnerClassSingleton staticInnerClassSingleton = new StaticInnerClassSingleton();
}
private static StaticInnerClassSingleton getInstance(){
return InnerClass.staticInnerClassSingleton;
}
//防止反射调用
private StaticInnerClassSingleton(){
if(InnerClass.staticInnerClassSingleton != null){
throw new RuntimeException("单例构造器禁止反射调用");
}
}
}
package com.Ljava.design.pattem.creational.singleton;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* @Auther 20173
* @Date 2019-4-8 11:52
* @Des 测试类
**/
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//饿汉模式 对象序列化
// HungrySingleton instance = HungrySingleton.getInstance();
// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\MyCode\\designPattem\\src\\main\\java\\com\\Ljava\\design\\pattem\\creational\\singleton\\instance_file.txt"));
// oos.writeObject(instance);
// File file = new File("D:\\MyCode\\designPattem\\src\\main\\java\\com\\Ljava\\design\\pattem\\creational\\singleton\\instance_file.txt");
// ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
// HungrySingleton newInstance = (HungrySingleton) ois.readObject();
// System.out.println(instance);
// System.out.println(newInstance);
//饿汉模式 反射破解单例模式
// Class objectClass = HungrySingleton.class;
// Constructor constructor = objectClass.getDeclaredConstructor();
// constructor.setAccessible(true);
// HungrySingleton instanceClass = HungrySingleton.getInstance();
// HungrySingleton newInstanceClass = (HungrySingleton) constructor.newInstance();
// System.out.println(instanceClass);
// System.out.println(newInstanceClass);
EnumInstance enumInstance = EnumInstance.getInstance();
enumInstance.prinTest();
}
}