Implementacja Singletona z Enum (w Javie)
Przeczytałem, że możliwe jest zaimplementowanie Singleton
w Javie za pomocą Enum
takiego jak:
public enum MySingleton {
INSTANCE;
}
Ale jak to działa? W szczególności należy utworzyć instancję Object
. Jak powstaje MySingleton
? Kto robi new MySingleton()
?
6 answers
To,
public enum MySingleton {
INSTANCE;
}
Ma ukryty konstruktor pusty. Bądźmy wyraźni,
public enum MySingleton {
INSTANCE;
private MySingleton() {
System.out.println("Here");
}
}
Jeśli następnie dodałeś kolejną klasę z main()
metodą jak
public static void main(String[] args) {
System.out.println(MySingleton.INSTANCE);
}
Zobaczysz
Here
INSTANCE
enum
pola są stałymi czasowymi kompilacji, ale są instancjami ich typu enum
. I, są one konstruowane, gdy typ enum jest odwołany po raz pierwszy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-09 18:31:35
Typ enum
jest specjalnym typem typu class
.
Twoja enum
deklaracja faktycznie kompiluje się do czegoś takiego jak
public final class MySingleton {
public final static MySingleton INSTANCE = new MySingleton();
private MySingleton(){}
}
Kiedy twój kod uzyska pierwszy dostęp INSTANCE
, klasa MySingleton
zostanie załadowana i zainicjalizowana przez JVM. Proces ten inicjalizuje pole static
powyżej raz (leniwie).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-11 18:01:28
Tworzenie klasy A Singleton może utrudnić testowanie jej klientów, ponieważ niemożliwe jest zastąpienie wzorcowej implementacji singletonem, chyba że implementuje interfejs, który służy jako jej typ. Zalecanym podejściem jest wdrożenie singletonów przez po prostu tworzy Typ enum z jednym elementem:
// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
To podejście jest funkcjonalnie równoważne z podejściem public field, z tą różnicą, że jest bardziej zwięzły, zapewnia maszynę serializacyjną za darmo i zapewnia żelazna gwarancja przed wieloma instancjami, nawet w obliczu wyrafinowanych ataki serializacyjne lub odbiciowe.
Choć podejście to nie jest jeszcze szeroko przyjęty, Jednoelementowy typ enum jest najlepszym sposobem implementacji singletonu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-10 06:08:50
Podobnie jak wszystkie instancje enum, Java tworzy instancje każdego obiektu po załadowaniu klasy, z pewnymi gwarancjami, że jest utworzona dokładnie raz na JVM . Pomyśl o deklaracji INSTANCE
jako publicznym statycznym polu końcowym: Java utworzy instancję obiektu przy pierwszym odwołaniu do klasy.
Instancje są tworzone podczas inicjalizacji statycznej, która jest zdefiniowana w specyfikacji języka Java, sekcja 12.4.
Jeśli to coś warte, Joshua Bloch opisuje ten wzór szczegółowo jako punkt 3 Effective Java Second Edition .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-08 22:21:45
Ponieważ Singleton Pattern polega na posiadaniu prywatnego konstruktora i wywołaniu jakiejś metody kontrolującej instancje (jak niektóre getInstance
), W Enumach mamy już ukryty prywatny konstruktor.
Nie wiem dokładnie, jak JVM lub jakiś kontener kontroluje instancje naszego Enums
, ale wygląda na to, że już używa implicit Singleton Pattern
, Różnica polega na tym, że nie nazywamy getInstance
, po prostu nazywamy Enum.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-12 07:02:07
Jak już wcześniej wspomniano, enum jest klasą Javy ze szczególnym warunkiem, że jej definicja musi zaczynać się od co najmniej jednej "stałej enum".
Część z tego, jest to klasa jak każda klasa i używasz jej, dodając metody poniżej definicji stałych:
public enum MySingleton {
INSTANCE;
public void doSomething() { ... }
public synchronized String getSomething() { return something; }
private String something;
}
Uzyskujesz dostęp do metod Singletona w następujący sposób:
MySingleton.INSTANCE.doSomething();
String something = MySingleton.INSTANCE.getSomething();
Użycie enum, zamiast klasy, jest, jak wspomniano w innych odpowiedziach, głównie o bezpiecznym wątku utworzenie singletonu i gwarancja, że zawsze będzie to tylko jedna kopia.
I, być może, najważniejsze, że takie zachowanie jest gwarantowane przez sam JVM i specyfikację Javy.
Oto sekcja ze specyfikacji Java na temat zapobiegania wielu instancjom instancji enum:
Typ enum nie ma instancji innych niż te zdefiniowane przez jego stałe enum. Jest to błąd w czasie kompilacji, aby próbować jawnie utworzyć instancję Typ enum. Ostateczna metoda klonowania w Enum zapewnia, że stałe enum nigdy nie mogą być klonowane, a specjalne traktowanie przez mechanizm serializacji zapewnia, że duplikaty instancji nigdy nie są tworzone w wyniku deserializacji. Zabronione jest tworzenie refleksyjnych instancji typów enum. Razem te cztery rzeczy zapewniają, że żadne instancje typu enum nie istnieją poza tymi zdefiniowanymi przez stałe enum.
Warto zauważyć, że po uruchomieniu wątku wszelkie obawy dotyczące bezpieczeństwa musi być traktowany jak w każdej innej klasie ze słowem kluczowym zsynchronizowanym itd.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-06 07:22:31