// *****************************现象描述*******************************
package com.example.SpringBootTest1.shejimoshi.singleton;
public class InnerclassSingleton {
private InnerclassSingleton() {};
private static class Singleton {
private static final InnerclassSingleton i = new InnerclassSingleton();
}
public static InnerclassSingleton getInstance() {
return Singleton.i;
}
}
// 通过反射获取对象拿到的对象不是同一个
public class Test {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Constructor<InnerclassSingleton> declaredConstructor = InnerclassSingleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
InnerclassSingleton instance1 = declaredConstructor.newInstance();
InnerclassSingleton instance2 = InnerclassSingleton.getInstance();
System.out.println(instance1 == instance2); // false
}
}
// *********************************防止漏洞攻击*****************************
package com.example.SpringBootTest1.shejimoshi.singleton;
public class InnerclassSingleton {
private InnerclassSingleton() {
if (InnerclassSingleton.getInstance() != null) {
throw new RuntimeException("单例模式不允许创建多个实例");
}
};
private static class Singleton {
private static final InnerclassSingleton i = new InnerclassSingleton();
}
public static InnerclassSingleton getInstance() {
return Singleton.i;
}
}
// 运行这段代码通过反射去创建实例时会报自定义异常, 从而达到防止反射漏洞攻击
public class Test {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Constructor<InnerclassSingleton> declaredConstructor = InnerclassSingleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
InnerclassSingleton instance1 = declaredConstructor.newInstance();
InnerclassSingleton instance2 = InnerclassSingleton.getInstance();
System.out.println(instance1 == instance2);
}
}