Qual è l'approccio migliore per utilizzare un Enum come singleton in Java?


85

Basandosi su ciò che è stato scritto nella domanda SO Migliore implementazione singleton in Java - vale a dire sull'uso di un enum per creare un singleton - quali sono le differenze / pro / contro tra (costruttore omesso)

public enum Elvis {
    INSTANCE;
    private int age;

    public int getAge() {
        return age;
    }
}

e poi chiamando Elvis.INSTANCE.getAge()

e

public enum Elvis {
    INSTANCE;
    private int age;

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

e poi chiamando Elvis.getAge()

Risposte:


96

Supponiamo che tu stia vincolando a qualcosa che utilizzerà le proprietà di qualsiasi oggetto che viene fornito - puoi passare Elvis.INSTANCE molto facilmente, ma non puoi passare Elvis.class e aspettarti che trovi la proprietà (a meno che non sia deliberatamente codificato per trovare proprietà statiche delle classi).

Fondamentalmente usi il pattern singleton solo quando vuoi un'istanza. Se i metodi statici funzionano bene per te, allora usali e non preoccuparti dell'enumerazione.


1
Perché non perdere tempo con l'enumerazione? C'è un modo migliore per fare singeltons in java5 +?
jontro

4
@jontro (ri) leggi la risposta; dice di usare le enumerazioni quando devi avere un singleton ma per evitare il singleton se puoi accontentarti di metodi statici
Miserable Variable

@MiserableVariable Ho commentato questo più di un anno fa. Non riesco davvero a ricordare a quale contesto mi riferivo.
jontro

non risponde alla domanda posta
Thufir

2
@ Thufir: Risponde alla parte "qual è la differenza" - che sembra essere ciò a cui l'OP era più interessato, dato che la risposta è stata accettata.
Jon Skeet

69

Un grande vantaggio è quando il tuo singleton deve implementare un'interfaccia. Seguendo il tuo esempio:

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

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

Con:

public interface HasAge {
    public int getAge();
}

Non si può fare con la statica ...


1
Può essere fatto con statics ... public static final HasAge INSTANCE = new HasAge () {private int age; @Override public int getAge () {return age; }}; ... quindi mi chiedo ancora cosa c'è di buono o di meglio nel metodo enum. Suppongo che se avessi bisogno di implementare due interfacce?
Sean Adkinson

9

I singleton (con stato) sono generalmente utilizzati per fingere di non utilizzare variabili statiche. Se non usi effettivamente la variabile statica pubblicamente, ingannerai meno persone.


8

Sceglierei l'opzione che è la più semplice e chiara. Questo è in qualche modo soggettivo, ma se non sai cosa è più chiaro, scegli l'opzione più breve.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.