Java反射和单例
为什么反射不能通过以下代码打破私有构造函数来打破单例模式。InstanceTwo上应该有一个新实例,但没有Java反射和单例,java,reflection,singleton,Java,Reflection,Singleton,为什么反射不能通过以下代码打破私有构造函数来打破单例模式。InstanceTwo上应该有一个新实例,但没有 Constructor[] constructors = EagerInitializedSingleton.class.getDeclaredConstructors(); for (Constructor constructor : constructors) { //Below code will destroy the singleton pattern construct
Constructor[] constructors = EagerInitializedSingleton.class.getDeclaredConstructors();
for (Constructor constructor : constructors) {
//Below code will destroy the singleton pattern
constructor.setAccessible(true);
instanceTwo = (EagerInitializedSingleton) constructor.newInstance();
break;
}
如果
InitializedSingleton
是一个枚举,则它不起作用。(我不评论它在其他情况下是否有效)
当然可以。为什么您认为它不能?如果
初始化Singleton
是枚举
,它能吗?(听起来好像不是,但我们实际上没有代码)。我之所以这样问,是因为Josh Bloch说过“即使面对复杂的序列化或反射攻击,也要严防多次实例化”,所以在打印instanceTwo的哈希时,我会遇到空指针异常。正如名字所示,初始化的singleTon是一个singleTon。这不是枚举。当您试图破坏类的不变量时出现异常这一事实是否意味着您不应该尝试这样做?我可以从第一行调用构造函数,根据文档,setAccessible(true)应该执行我想要的操作,并且不存在这样的异常。它不是枚举。这是一个单例类,正如名字所示,我正在使用急切初始化。枚举是一个急切初始化的单例。Ok。但该类不是enum。这是一个单例类,我想打破私有构造函数,再创建一个实例。如果它是单例类,为什么还要第二个实例?在特殊情况下不是单例的单例不是单例。更改类,使其不是单例,或将其作为单例使用。使用黑客和预兆迫使它成为它不是的东西不是正确的方法。
class Ideone
{
enum EagerInitializedSingleton { INSTANCE }
public static void main (String[] args) throws java.lang.Exception
{
Constructor[] constructors = EagerInitializedSingleton.class.getDeclaredConstructors();
for (Constructor constructor : constructors) {
//Below code will destroy the singleton pattern
constructor.setAccessible(true);
System.out.println((EagerInitializedSingleton) constructor.newInstance());
}
}
}
Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects
at java.lang.reflect.Constructor.newInstance(Constructor.java:416)
at Ideone.main(Main.java:19)