2016-04-15 15 views
-1

Warum Reflexion Singleton-Muster nicht brechen kann, indem der private Konstruktor durch den folgenden Code unterbrochen wird. Es sollte eine neue Instance auf InstancTwo geben, aber nicht.Java Reflection und Singleton

Constructor[] constructors = EagerInitializedSingleton.class.getDeclaredConstructors(); 
for (Constructor constructor : constructors) { 
    //Below code will destroy the singleton pattern 
    constructor.setAccessible(true); 
    instanceTwo = (EagerInitializedSingleton) constructor.newInstance(); 
    break; 
} 
+1

Sicher kann es. Warum denkst du, kann es nicht? –

+1

Kann es sein, wenn'EagerInitializedSingleton' eine 'enum' ist? (Es klingt nicht wie es ist, aber wir haben nicht wirklich den Code). Ich frage nach dem, was Josh Bloch über die "eiserne Garantie gegen mehrfache Instanziierung, selbst angesichts ausgeklügelter Serialisierungs- oder Reflektionsangriffe" sagt. –

+0

Ich erhalte eine Nullzeiger-Ausnahme beim Drucken von Hash für instanceTwo. EagerInitializedSingleton ist ein singleTon, wie der Name vermuten lässt. Dies ist nicht enum. –

Antwort

1

Es funktioniert nicht, wenn EagerInitializedSingleton eine Enumeration ist. (Ich mache keinen Kommentar darüber, ob es funktioniert in anderen Fällen)

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()); 
     } 
    } 
} 

Ideone demo

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) 
+0

Es ist nicht enum. Es ist eine Singleton-Klasse und ich verwende eifrig Initialisierung, wie der Name vermuten lässt. –

+0

Ein Enum * ist * ein eifrig initialisierter Singleton. –

+0

Ok. Aber die Klasse ist nicht enum. Es ist eine Singleton-Klasse, und ich möchte privaten Konstruktor brechen, um eine weitere Instanz zu erstellen. –