1.1
饿汉式不改成员变量:有效防止反射,
当反射在前,先类加载,再反射构造方法(此时判断出已有实例)。
当反射在后,先反射构造方法(此时判断出已有实例)。
public class HungrySingleton {
private final static HungrySingleton hungrySingleton;
static{
hungrySingleton = new HungrySingleton();
}
private HungrySingleton(){
if(hungrySingleton != null){
throw new RuntimeException("单例构造器禁止反射调用");
}
}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
}
1.2
饿汉式改成员变量为null:如果不设final,
当反射在前,先类加载,再反射构造方法(此时判断出成员变量为null)。
当反射在后,先反射构造方法(此时判断出成员变量为null)。
2.1
内部类延迟加载不改成员变量:有效防止反射,
当反射在前,先反射构造方法,构造方法内部的判空导致innerclass类加载,相当于构造方法嵌套调用构造方法,外层的构造方法判断出已有实例。
当反射在后,构造方法判断出已有实例。
内部类延迟加载成员变量为null:如果不设final,
当反射在前,innerclass先类加载,再反射构造方法(此时判断出成员变量为null)。
public class StaticInnerClassSingleton {
private static class InnerClass{
private static StaticInnerClassSingleton staticInnerClassSingleton
= new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance(){
return InnerClass.staticInnerClassSingleton;
}
private StaticInnerClassSingleton(){
if(InnerClass.staticInnerClassSingleton != null){
throw new RuntimeException("单例构造器禁止反射调用");
}
}
}
2.2
懒汉式不改成员变量:
当反射在前,不能防止攻击。
当反射在后,能防止攻击。
懒汉式改成员变量为null:任何顺序都不能防止攻击。