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:

Klauzula extends nie jest dozwolona dla enum

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!