饿汉模式-序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package tech.xixing.design.pattern.creational.singleton;
import java.io.Serializable;
public class HungrySingleton implements Serializable {
private final static HungrySingleton hungrySingleton; static { hungrySingleton=new HungrySingleton(); } private HungrySingleton(){
}
public static HungrySingleton getInstance(){ return hungrySingleton; }
private Object readResolve(){ return hungrySingleton; }
}
|
在最后加入方法readResolve()即可在反序列化中返回原来对象。
反射攻击预防
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package tech.xixing.design.pattern.creational.singleton;
import java.io.Serializable;
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; }
private Object readResolve(){ return hungrySingleton; }
}
|
懒汉模式
对于懒汉模式,并不能对反射攻击进行有效防御
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package tech.xixing.design.pattern.creational.singleton;
public class LazySingleton { private static LazySingleton lazySingleton=null;
private static boolean flag=true;
private LazySingleton(){ if(!flag){ throw new RuntimeException("单例模式禁止反射"); }else { flag=false; }
}
public synchronized static LazySingleton getInstance(){ if(lazySingleton==null){ lazySingleton=new LazySingleton(); } return lazySingleton;
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12
| Class objectClass=LazySingleton.class; LazySingleton lazySingleton = LazySingleton.getInstance(); Field flag=lazySingleton.getClass().getDeclaredField("flag"); flag.setAccessible(true); flag.set(lazySingleton,true); Constructor constructor=objectClass.getDeclaredConstructor(); constructor.setAccessible(true); LazySingleton lazySingleton1 = (LazySingleton) constructor.newInstance();
System.out.println(lazySingleton); System.out.println(lazySingleton1);
|