rob*_*bin 1 java design-patterns
我遇到了以下示例,其中可以使用反射来实例化单例类。代码如下
public class SingletonExploitationExample {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
MySingleTon.getInstance();
Constructor<MySingleTon> constructor = MySingleTon.class.getDeclaredConstructor();
constructor.setAccessible(true);
MySingleTon obj1 = constructor.newInstance();
MySingleTon obj2 = constructor.newInstance();
MySingleTon obj3 = constructor.newInstance();
obj1.printN();
}
}
final class MySingleTon {
private static MySingleTon instance = null;
private static int count = 0;
private MySingleTon(){
count++;
}
public void printN(){
System.out.println(count);
}
public static MySingleTon getInstance(){
if(instance == null){
synchronized (MySingleTon.class){
if(instance == null){
instance = new MySingleTon();
}
}
}
return instance;
}
}
Run Code Online (Sandbox Code Playgroud)
有什么办法可以避免这种情况,或者使一个实例只有一个实例(通过反射用户也不能实例化一个新对象)?
是的,带enums!
枚举使功能强大的线程安全,“类加载器安全”的单例成为可能,并且无法通过反射进行初始化!
这是一个例子。
enum Foo {
INSTANCE;
}
Class<?> fooClass = Foo.class;
Constructor<?> c = fooClass.getDeclaredConstructors()[0];
c.setAccessible(true);
Foo f = (Foo)c.newInstance();
Run Code Online (Sandbox Code Playgroud)
输出量
java.lang.IllegalArgumentException: Cannot reflectively create enum objects
at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
at ...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
249 次 |
| 最近记录: |