Du har nylig fordypet deg i singleton-designmønsteret , hvordan du implementerer det i Java, og hva det er for. Men hva om jeg forteller deg at Java kommer med sin egen singleton ut av esken? fascinert? Så la oss dykke inn.

Du vet sikkert allerede om Enum-klassen . Den har en spesiell funksjon som du bør være klar over. Nærmere bestemt implementerer Enum singleton-designmønsteret. Dette alternativet er nesten det samme som singleton-tilnærmingen som involverer et offentlig felt.

Singleton som enum:


public enum Device {   
    PRINTER	
} 
    

Singleton som en offentlig variabel:


public class Printer {   
    public static final Printer PRINTER = new Printer();   
    private Printer() {
    }
//…
}
    

Enum - tilnærmingen er mer kompakt enn offentlig felt-tilnærmingen, siden vi ikke trenger å skrive vår egen implementering. Viktigst av alt, enums har ingen problemer med serialisering.

Serialisering av enums fungerer annerledes enn det gjør for vanlige objekter: bare verdien av enum-navnet serialiseres. Under deserialisering brukes metoden med det deserialiserte navnet for å få en forekomst. I tillegg kan enum beskytte deg mot refleksjonsangrep .

Du vil lære mer om refleksjon i leksjonene i den andre modulen, hvor vi vil utforske Reflection API .

Java forbyr instansiering av enums - en begrensning bakt inn i implementeringen av Constructor -klassens newInstance -metode, som ofte kalles når du lager objekter gjennom refleksjon.

Utdrag av kode fra Constructor.newInstance . Brukes til å lage en enum :


if ((clazz.getModifiers() & Modifier.ENUM) != 0)
    throw new IllegalArgumentException("Cannot reflectively create enum objects");
    

Ulempene med å bruke en enum for å lage en singleton inkluderer:

  • Mangel på lat initialisering, siden objektet opprettes umiddelbart og initialisering ikke kan forsinkes.

  • Andre klasser kan ikke utvides. Det vil si at i tilfeller der du trenger å arve en annen klasse, vil det ikke fungere å bruke en enum som singleton. I slike tilfeller må vi vende oss til de andre implementeringsalternativene som allerede er kjent for oss: en statisk metode eller en offentlig variabel.

  • Når du bruker enum som singleton, kan du bare bruke ett enum- felt.


public enum Device extends Electricity { 
    PRINTER 
}
    

Denne koden vil gi oss en kompileringsfeil:

Ingen utvidelsesklausul tillatt for enum

Men hvis vi trenger å implementere et grensesnitt, er det ikke noe problem, siden enum kan implementere grensesnitt:


public enum Device implements Electricity { 
    PRINTER 
}
    

Hvis du ikke trenger å bruke arv, er det best å implementere singleton-mønsteret via enum . Vi er ikke alene om å anbefale dette – Joshua Bloch selv gjør det også .

Denne implementeringstilnærmingen gir deg bekvemmelighet, kompakthet, serialisering ut av esken, beskyttelse mot refleksjonsangrep og unikhet - alt som en god singleton trenger!