instrukcja switch w Javie
Niedawno dowiedzieliśmy się, czym jest Singleton , jak go zaimplementować w Javie i do czego służy. Ale co, jeśli powiem ci, że Java ma już swój własny singleton po wyjęciu z pudełka? Ciekawy? Więc wymyślmy to.
Prawdopodobnie znasz już klasę enum . Ma funkcję, o której powinieneś wiedzieć. Chodzi o to, że enum jest implementacją singletona. Ta opcja jest prawie taka sama, jak podejście do pola publicznego .
Singleton jako wyliczenie:
public enum Device {
PRINTER
}
pojedyncza zmienna publiczna:
public class Printer {
public static final Printer PRINTER = new Printer();
private Printer() {
}
//…
}
W przypadku pola publicznego opcja enum jest bardziej kompaktowa - nie trzeba pisać własnej implementacji. A co najważniejsze, enamy nie mają problemów z serializacją.
Serializacja działa tutaj inaczej niż w przypadku zwykłych obiektów: serializowana jest tylko wartość nazwy enam. Podczas deserializacji metoda jest używana z deserializowaną nazwą, aby uzyskać instancję. Ponadto enum pozwala chronić się przed atakami odruchowymi .
Więcej o Reflection dowiesz się z wykładów drugiego modułu, w temacie Reflection API . |
Java wprowadza zakaz tworzenia instancji enamów, co jest zakodowane w implementacji metody newInstance klasy Constructor , która jest często wywoływana podczas tworzenia obiektów poprzez odbicie.
Część kodu z Constructor.newInstance do utworzenia enum :
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
Z minusów tworzenia Singletona przez enum warto wspomnieć:
Brak leniwej inicjalizacji, ponieważ obiekt jest tworzony natychmiast i nie można wykonać leniwej inicjalizacji.
Nie ma możliwości przedłużenia o inne zajęcia. Oznacza to, że użycie enum jako Singleton w przypadkach, w których musisz dziedziczyć z innej klasy, nie będzie działać. W takich przypadkach musimy odwołać się do znanych nam już opcji implementacji poprzez metodę statyczną lub zmienną publiczną.
Używając wyliczenia jako singletonu, możesz użyć tylko jednego pola w klasie wyliczenia .
public enum Device extends Electricity {
PRINTER
}
Ten kod zwróci nam błąd kompilacji:
Ale jeśli musimy zaimplementować interfejs, nie ma problemu: wyliczenia mogą implementować interfejsy:
public enum Device implements Electricity {
PRINTER
}
Jeśli nie musisz korzystać z dziedziczenia, lepiej użyć implementacji Singleton poprzez enum . Radzimy więc nie tylko nam, ale samemu Joshua Blochowi .
Korzystanie z takiej implementacji daje wygodę, zwartość, serializację od razu po wyjęciu z pudełka, ochronę przed odruchowymi atakami i unikalność, a tego właśnie potrzebuje dobry Singleton!
GO TO FULL VERSION