![translation](https://cdn.durumis.com/common/trans.png)
Dit is een door AI vertaalde post.
[Effectieve Java] Item 3. Garandeer singleton met een private constructor of een enum-type
- Taal van de tekst: Koreaans
- •
-
Referentieland: Alle landen
- •
- Informatietechnologie
Selecteer taal
Samengevat door durumis AI
- Een singleton is een klasse die slechts één instantie kan genereren en wordt gebruikt om stateless objecten of unieke systeemcomponenten te maken.
- Er zijn drie manieren om een singleton te maken: een methode waarbij het public static-lid een final-veld is, een methode waarbij een statische fabriekmethode wordt aangeboden, en een methode die een enum-type gebruikt. De methode die een enum-type gebruikt, is de beste.
- Bij het serialiseren van een singleton-klasse moet je Serializable implementeren, alle instantievelden als transient declareren en de readResolve()-methode overschrijven.
Singleton
Het concept van singleton
Een singleton is een klasse die slechts één instantie kan creëren. Een typisch voorbeeld van een singleton is een stateless object of een uniek systeemcomponent. Singleton-klassen zijn echter moeilijk te testen als ze niet zijn gedefinieerd als een type met een interface en een implementatie ervan.
Manieren om een singleton te maken
Public static member als final veld
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {
}
public void speak() {
System.out.println("elvis");
}
De private constructor wordt slechts één keer aangeroepen tijdens het initialiseren van de Elvis-instantie en garandeert dat het de enige instantie in het hele systeem is. Het is echter mogelijk om de private constructor aan te roepen met AccessibleObject.setAccessible(), maar deze methode met reflectie kan worden geblokkeerd door een uitzondering te genereren wanneer een tweede object wordt aangemaakt.
- Voordelen
- Het is duidelijk uit de API dat deze klasse een singleton is.
- Concis.
Publieke statische fabrieksmethode leveren
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() {
}
public static Elvis getInstance() {
return INSTANCE;
}
public void speak() {
System.out.println("elvis");
}
Behalve door manipulatie via reflectie, zorgt deze methode er ook voor dat het de enige instantie in het hele systeem is. Het veld wordt simpelweg private gemaakt en het object wordt geretourneerd door middel van een statische fabrieksmethode.
- Voordelen
- Het is mogelijk om een singleton te veranderen zonder de API te
wijzigen.
- De statische fabrieksmethode kan bijvoorbeeld een andere instantie per thread retourneren.
- Het is mogelijk om een generieke singleton-fabrieksmethode te maken.
- Het is mogelijk om een methode-referentie van een statische
fabrieksmethode te gebruiken als leverancier.
- Bijvoorbeeld, in plaats van Elvis::getInstance, kan Supplier<Elvis> worden gebruikt.
- Het is mogelijk om een singleton te veranderen zonder de API te
wijzigen.
Als de bovenstaande voordelen niet relevant zijn, is het beter om de eerste methode te gebruiken.
De enumeratiemethode gebruiken
public enum Elvis {
INSTANCE;
public void speak() {
System.out.println("elvis");
}
De beste methode is om een enumeratie te gebruiken. Deze methode is veiliger tegen reflectie-aanvallen dan de bovenstaande twee methoden en de code is cleaner. De twee bovenstaande methoden hebben ook het nadeel dat ze extra code moeten worden toegevoegd tijdens het serialiseren. Dit wordt later besproken.
Het is echter noodzakelijk om er rekening mee te houden dat terwijl een singleton die wordt gecreëerd, een interface kan erven, het niet mogelijk is om een klasse te erven.
Zaken om op te letten bij het serialiseren van een singleton-klasse
Als u een singleton-klasse serialiseert die is gemaakt met de eerste of tweede methode, moet u, behalve het implementeren van Serializable, alle instantievariabelen als transient declareren en de readResolve()-methode opnieuw definiëren.
private Object readResolve throws ObjectStreamException {
return INSTANCE;
Bron
- Effectieve Java
- https://catsbi.oopy.io/d7f3a636-b613-453b-91c7-655d71fda2b1