我有这个简单枚举充当一个Singleton提供商为Object
类型的对象辛格尔顿总是可以反映(反射甚至枚举)
package package2;
public enum SingletonEnum {
INSTANCE;
private Object obj = new Object();
public Object getObject() {
return obj;
}
}
,我有这个样品主要反映现场情况,修改通过分配新对象字段
package package2;
import java.lang.reflect.Field;
public class Sample2 {
public static void main(String[] args) {
Object obj = SingletonEnum.INSTANCE.getObject();
System.out.println(obj.hashCode());
try {
Class<?> clazz = Class.forName("package2.SingletonEnum");
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.getType().equals(Object.class)) {
field.setAccessible(true);
field.set(SingletonEnum.INSTANCE, new Object());
}
}
}
catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(SingletonEnum.INSTANCE.getObject().hashCode());
}
}
输出是
1554514352
2112239710
显示两个不同的哈希码,我假设有两个引用。这怎么可能?我认为枚举Singletons是使Singleton“Singleton”不能被反射的唯一方法,所以这只意味着只有SecurityManager
可以禁止所有的反射。所以我的问题是......“什么”是禁止一个Singleton对象实例化的最安全的方法?
目前还不清楚你在问什么。 'SingletonEnum.INSTANCE' *是*单身人士。这并不意味着它是不可变的。此外,当你修改单例的字段时,其他对象的实例化不会发生,当你执行'new Object()'时,它已经发生了。 – Holger