Was ist der beste Ansatz für die Verwendung einer Enum als Singleton in Java?

85

Aufbauend auf dem, was in der SO-Frage geschrieben wurde. Beste Singleton-Implementierung in Java - nämlich über die Verwendung einer Aufzählung zum Erstellen eines Singletons - Was sind die Unterschiede / Vor- / Nachteile zwischen (Konstruktor weggelassen)?

public enum Elvis {
    INSTANCE;
    private int age;

    public int getAge() {
        return age;
    }
}

und dann anrufen Elvis.INSTANCE.getAge()

und

public enum Elvis {
    INSTANCE;
    private int age;

    public static int getAge() {
        return INSTANCE.age;
    }
}

und dann anrufen Elvis.getAge()

Meilen D.
quelle

Antworten:

96

Angenommen, Sie sind an etwas gebunden, das die Eigenschaften eines bestimmten Objekts verwendet. Sie können Elvis.INSTANCE sehr einfach übergeben, aber Sie können Elvis.class nicht übergeben und erwarten, dass es die Eigenschaft findet (es sei denn, es ist absichtlich codiert, um es zu finden) statische Eigenschaften von Klassen).

Grundsätzlich verwenden Sie das Singleton-Muster nur, wenn Sie eine Instanz möchten . Wenn statische Methoden für Sie in Ordnung sind, verwenden Sie diese einfach und kümmern Sie sich nicht um die Aufzählung.

Jon Skeet
quelle
1
Warum nicht mit der Aufzählung beschäftigen? Gibt es eine bessere Möglichkeit, Singeltons in Java5 + zu erstellen?
10.
4
@jontro (erneut) die Antwort lesen; er sagt, Enums zu verwenden, wenn Sie einen Singleton haben müssen, aber Singleton zu vermeiden, wenn Sie mit statischen Methoden auskommen können
Miserable Variable
@MiserableVariable Ich habe dies vor über einem Jahr kommentiert. Ich kann mich nicht wirklich erinnern, auf welchen Kontext ich mich bezog.
Jontro
beantwortet die gestellte Frage nicht
Thufir
2
@Thufir: Es beantwortet den Teil "Was ist der Unterschied?" - was anscheinend das ist, woran das OP am meisten interessiert war, da die Antwort akzeptiert wurde.
Jon Skeet
69

Ein großer Vorteil ist, wenn Ihr Singleton eine Schnittstelle implementieren muss. Folgen Sie Ihrem Beispiel:

public enum Elvis implements HasAge {
    INSTANCE;
    private int age;

    @Override
    public int getAge() {
        return age;
    }
}

Mit:

public interface HasAge {
    public int getAge();
}

Mit Statik geht das nicht ...

Nicolas
quelle
1
Es kann mit Statik gemacht werden ... public static final HasAge INSTANCE = new HasAge () {private int age; @Override public int getAge () {Rückgabealter; }}; ... also frage ich mich immer noch, was gut oder besser an der Aufzählungsmethode ist. Ich nehme an, wenn Sie zwei Schnittstellen implementieren müssten?
Sean Adkinson
9

(Stateful) Singletons werden im Allgemeinen verwendet, um vorzutäuschen, keine statischen Variablen zu verwenden. Wenn Sie die öffentlich statische Variable nicht tatsächlich verwenden, werden Sie weniger Leute zum Narren halten.

Tom Hawtin - Tackline
quelle
8

Ich würde die einfachste und klarste Option wählen. Dies ist etwas subjektiv, aber wenn Sie nicht wissen, was am klarsten ist, wählen Sie einfach die kürzeste Option.

Peter Lawrey
quelle