2016-04-15 4 views
-1

Почему отражение не может сломать одноэлементный шаблон, разбив частный конструктор на код ниже. На InstanctTwo должен появиться новый экземпляр, но его нет.Java Reflection and 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

Конечно, может. Почему вы думаете, что это невозможно? –

+1

Может ли это, если 'EagerInitializedSingleton' является' enum'? (Это звучит не так, но на самом деле у нас нет кода). Я спрашиваю, из-за чего Джош Блох говорит о «железной гарантии от множественного экземпляра, даже перед лицом сложных атак с сериализацией или отражением». –

+0

Я получаю исключение с помощью исключающего указателя при печати хэша, например, дважды. EagerInitializedSingleton - это singleTon, как следует из названия. Это не перечисление. –

ответ

1

Это не работает, если EagerInitializedSingleton является перечислением. (Я не делаю никаких комментариев по поводу работает ли он в других случаях)

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

Его не перечисление. Его класс singleton, и я использую нетерпеливую инициализацию, как следует из названия. –

+0

Перечисление * - * нетерпеливо инициализированный синглтон. –

+0

Хорошо. Но класс не является перечислением. Его класс singleton, и я хотел бы разбить частный конструктор, чтобы создать еще один экземпляр. –