Meta title: Java Singleton: guida completa al Singleton Pattern in Java
Meta description: Scopri cos’è un Java Singleton, come creare una singleton class in Java, esempi pratici, implementazioni thread safe, enum singleton e differenze con Spring.
Slug consigliato: java-singleton
Keyword principale: java singleton
Keyword correlate: singleton pattern java, singleton design pattern java, singleton implementation in java, singleton java, singleton in java, singleton class in java, java singleton pattern, java singleton thread safe, singleton annotation java, java singleton example

Il Java Singleton è uno dei design pattern più conosciuti nello sviluppo software. Quando si studiano i pattern creazionali, il Singleton Pattern in Java è quasi sempre uno dei primi esempi affrontati, perché introduce un concetto semplice ma molto importante: garantire che una classe abbia una sola istanza e fornire un punto di accesso globale a quell’istanza.

In altre parole, una singleton class in Java è una classe progettata per creare un solo oggetto durante l’esecuzione dell’applicazione. Tutte le parti del programma che hanno bisogno di quell’oggetto non ne creano uno nuovo, ma recuperano sempre la stessa istanza.

Questo può essere utile in diversi scenari: configurazioni globali, logger, gestori di cache, accesso controllato a risorse condivise, factory, servizi interni o componenti che devono esistere una sola volta nel contesto dell’applicazione.

Il singleton design pattern Java sembra facile da implementare, ma nasconde alcune insidie. Una cattiva implementazione può creare problemi in ambienti multithread, può non essere sicura con la serializzazione, può essere violata tramite reflection o può introdurre dipendenze globali difficili da testare.

Per questo motivo, in questa guida vedremo cos’è il Singleton, come funziona, come creare una classe Singleton in Java, quali implementazioni usare, quali evitare e quando questo pattern è davvero utile.

Cos’è il Singleton Pattern in Java

Il Singleton Pattern Java è un design pattern creazionale che ha lo scopo di limitare la creazione di oggetti di una determinata classe a una sola istanza.

La definizione classica è la seguente: il Singleton garantisce che una classe abbia una sola istanza e fornisce un punto di accesso globale a tale istanza.

Questa definizione contiene due aspetti fondamentali.

Il primo è il controllo dell’istanza. La classe non deve poter essere istanziata liberamente dall’esterno tramite new. Per questo motivo, il costruttore viene reso privato.

Il secondo è il punto di accesso globale. Poiché l’utente della classe non può creare direttamente l’oggetto, la classe deve esporre un metodo statico, di solito chiamato getInstance(), che restituisce l’unica istanza disponibile.

In sintesi, una classe singleton Java segue tre regole principali:

  • ha un costruttore privato;

  • conserva internamente una propria istanza statica;

  • espone un metodo pubblico e statico per recuperare l’istanza.

Il risultato è una classe che controlla direttamente il proprio ciclo di vita.

Perché usare un Java Singleton

Un Java Singleton viene usato quando ha senso avere una sola istanza condivisa di una classe.

Un esempio tipico è un logger. In molte applicazioni può essere utile avere un unico componente responsabile della scrittura dei log. Un altro esempio è una classe di configurazione che carica impostazioni comuni e le rende disponibili a più parti dell’applicazione.

Il Singleton può essere utile anche per gestire una cache interna, una factory, un registro di oggetti, un componente di monitoraggio o un servizio che deve coordinare una risorsa condivisa.

Tuttavia, il Singleton non deve essere usato ovunque. Il fatto che sia semplice da capire non significa che sia sempre la scelta migliore. Un uso eccessivo del pattern può rendere il codice più difficile da testare, più rigido e più dipendente da uno stato globale condiviso.

Il singleton Java design pattern è utile quando la singola istanza è una vera esigenza del dominio o dell’architettura. Se invece viene usato solo per evitare di passare dipendenze tra classi, può diventare un problema di progettazione.

Implementazione base di una Singleton Class in Java

Il modo più semplice per creare una singleton class in Java consiste nel rendere privato il costruttore e nel fornire un metodo statico per ottenere l’istanza.

Ecco un primo esempio di singleton implementation in Java:

public class BasicSingleton {
 private static BasicSingleton instance;
 private BasicSingleton() {
 // Costruttore privato
 }
 public static BasicSingleton getInstance() {
 if (instance == null) {
 instance = new BasicSingleton();
 }
 return instance;
 }
}

Questa implementazione è semplice e facile da leggere. Quando il metodo getInstance() viene chiamato per la prima volta, la variabile instance è null, quindi viene creato un nuovo oggetto. Dalla seconda chiamata in poi, l’oggetto esiste già e viene semplicemente restituito.

Questo approccio usa la cosiddetta lazy initialization, cioè l’inizializzazione ritardata. L’istanza non viene creata quando la classe viene caricata, ma solo quando serve davvero.

Dal punto di vista didattico, questo è un buon java singleton example, perché mostra chiaramente la logica del pattern. Tuttavia, questa versione non è sicura in ambienti multithread.

Example of Singleton Pattern in Java

Per capire meglio il comportamento del Singleton, possiamo aggiungere una proprietà alla classe e verificare che due variabili diverse puntino in realtà allo stesso oggetto.

public class BasicSingleton {
 private static BasicSingleton instance;
 private String value;
 private BasicSingleton() {
 }
 public static BasicSingleton getInstance() {
 if (instance == null) {
 instance = new BasicSingleton();
 }
 return instance;
 }
 public String getValue() {
 return value;
 }
 public void setValue(String value) {
 this.value = value;
 }
}

E ora possiamo usare la classe in questo modo:

public class Main {
 public static void main(String[] args) {
 BasicSingleton first = BasicSingleton.getInstance();
 BasicSingleton second = BasicSingleton.getInstance();
 first.setValue("Sono l'unica istanza Singleton");
 System.out.println(second.getValue());
 System.out.println(first == second);
 }
}

L’output sarà:

Sono l'unica istanza Singleton
true

Il risultato true conferma che first e second non sono due oggetti diversi, ma due riferimenti alla stessa istanza.

Questo è un semplice singleton example in Java, utile per comprendere il concetto di base. Tuttavia, come vedremo, non è ancora una soluzione adatta a tutti gli scenari.

Il problema del multithreading

La prima implementazione del Singleton funziona correttamente in un programma single-thread. Il problema nasce quando più thread chiamano getInstance() nello stesso momento.

Immaginiamo che due thread entrino contemporaneamente in questo blocco:

if (instance == null) {
 instance = new BasicSingleton();
}

Se entrambi leggono instance == null prima che uno dei due completi la creazione dell’oggetto, entrambi potrebbero creare una nuova istanza. In questo caso il pattern verrebbe rotto, perché non avremmo più una sola istanza.

Questo è il motivo per cui, nelle applicazioni reali, è importante parlare di java singleton thread safe, singleton thread safe Java e java thread safe singleton.

Un Singleton è thread safe quando garantisce la creazione di una sola istanza anche in presenza di più thread concorrenti.

Thread Safe Singleton con synchronized

Una prima soluzione consiste nel rendere il metodo getInstance() sincronizzato.

public class ThreadSafeSingleton {
 private static ThreadSafeSingleton instance;
 private ThreadSafeSingleton() {
 }
 public static synchronized ThreadSafeSingleton getInstance() {
 if (instance == null) {
 instance = new ThreadSafeSingleton();
 }
 return instance;
 }
}

In questo modo, un solo thread alla volta può eseguire il metodo getInstance(). Questo impedisce la creazione simultanea di più oggetti.

La soluzione è corretta, ma può avere un costo prestazionale. Ogni chiamata a getInstance() deve passare attraverso la sincronizzazione, anche dopo che l’istanza è già stata creata. In molte applicazioni questo costo è trascurabile, ma in scenari ad alte prestazioni può essere evitato con implementazioni più efficienti.

Double-Checked Locking Singleton

Un’alternativa più ottimizzata è il Double-Checked Locking. Questa tecnica controlla due volte se l’istanza è null: una prima volta prima del blocco sincronizzato e una seconda volta dentro il blocco.

public class DoubleCheckedSingleton {
 private static volatile DoubleCheckedSingleton instance;
 private DoubleCheckedSingleton() {
 }
 public static DoubleCheckedSingleton getInstance() {
 if (instance == null) {
 synchronized (DoubleCheckedSingleton.class) {
 if (instance == null) {
 instance = new DoubleCheckedSingleton();
 }
 }
 }
 return instance;
 }
}

In questa implementazione, la variabile instance deve essere dichiarata volatile.

La parola chiave volatile è importante perché garantisce la visibilità delle modifiche tra thread. Senza volatile, un thread potrebbe vedere un riferimento a un oggetto non completamente inizializzato, causando comportamenti difficili da prevedere.

Questa è una delle implementazioni più note quando si parla di singleton implementation Java e singleton Java thread safe. Tuttavia, anche se è valida, non sempre è la più semplice o la più elegante.

Eager Initialization Singleton

Un altro modo per creare un Singleton consiste nell’inizializzare subito l’istanza, nel momento in cui la classe viene caricata.

public class EagerSingleton {
 private static final EagerSingleton INSTANCE = new EagerSingleton();
 private EagerSingleton() {
 }
 public static EagerSingleton getInstance() {
 return INSTANCE;
 }
}

Questa soluzione è thread safe perché l’inizializzazione delle classi in Java è gestita dalla JVM in modo sicuro. L’istanza viene creata una sola volta e il metodo getInstance() restituisce sempre lo stesso oggetto.

Il vantaggio è la semplicità. Non servono blocchi synchronized, non serve volatile e il codice è facile da leggere.

Lo svantaggio è che l’istanza viene creata anche se non verrà mai usata. Se l’oggetto è leggero, questo non è un problema. Se invece la classe inizializza risorse costose, connessioni, file o strutture pesanti, può essere preferibile una soluzione lazy.

Singleton con Static Block

Una variante dell’eager initialization utilizza un blocco statico. Questo approccio può essere utile quando la creazione dell’istanza richiede una logica più articolata o la gestione di eccezioni.

public class StaticBlockSingleton {
 private static final StaticBlockSingleton INSTANCE;
 static {
 try {
 INSTANCE = new StaticBlockSingleton();
 } catch (Exception e) {
 throw new RuntimeException("Errore durante la creazione del Singleton", e);
 }
 }
 private StaticBlockSingleton() {
 }
 public static StaticBlockSingleton getInstance() {
 return INSTANCE;
 }
}

Anche questa soluzione è thread safe, ma rimane eager: l’istanza viene creata al caricamento della classe.

Bill Pugh Singleton

Una delle implementazioni più apprezzate del Java Singleton Pattern è il cosiddetto Bill Pugh Singleton, basato su una classe statica interna.

public class BillPughSingleton {
 private BillPughSingleton() {
 }
 private static class SingletonHolder {
 private static final BillPughSingleton INSTANCE = new BillPughSingleton();
 }
 public static BillPughSingleton getInstance() {
 return SingletonHolder.INSTANCE;
 }
}

Questa soluzione è elegante perché combina lazy initialization e thread safety.

La classe interna SingletonHolder non viene caricata finché non viene chiamato getInstance(). Quando questo accade, la JVM inizializza la classe interna e crea l’istanza in modo sicuro.

Il vantaggio è che non servono né synchronized né volatile. Per molte applicazioni Java tradizionali, questa è una delle migliori implementazioni manuali del Singleton.

Enum Singleton in Java

Un’altra implementazione molto robusta consiste nell’usare un enum.

public enum EnumSingleton {
 INSTANCE;
 public void execute() {
 System.out.println("Esecuzione dal Singleton");
 }
}

Utilizzo:

public class Main {
 public static void main(String[] args) {
 EnumSingleton.INSTANCE.execute();
 }
}

Il Singleton con enum è molto compatto e offre diversi vantaggi. È thread safe, gestisce meglio la serializzazione ed evita molti problemi tipici delle implementazioni manuali.

Questa soluzione è spesso consigliata quando si vuole un Singleton semplice, robusto e senza necessità di estendere altre classi. Tuttavia, non sempre è la scelta più flessibile, soprattutto quando servono inizializzazioni complesse, ereditarietà o integrazione con framework di dependency injection.

Singleton e serializzazione

Un problema spesso ignorato riguarda la serializzazione.

Se una classe Singleton implementa Serializable, durante la deserializzazione potrebbe essere creata una nuova istanza, rompendo il vincolo del Singleton.

Esempio:

import java.io.Serializable;
public class SerializableSingleton implements Serializable {
 private static final long serialVersionUID = 1L;
 private static final SerializableSingleton INSTANCE = new SerializableSingleton();
 private SerializableSingleton() {
 }
 public static SerializableSingleton getInstance() {
 return INSTANCE;
 }
}

Per evitare che la deserializzazione crei una nuova istanza, è possibile implementare il metodo readResolve():

protected Object readResolve() {
 return getInstance();
}

La classe completa diventa:

import java.io.Serializable;
public class SerializableSingleton implements Serializable {
 private static final long serialVersionUID = 1L;
 private static final SerializableSingleton INSTANCE = new SerializableSingleton();
 private SerializableSingleton() {
 }
 public static SerializableSingleton getInstance() {
 return INSTANCE;
 }
 protected Object readResolve() {
 return getInstance();
 }
}

Questo è un dettaglio importante quando si studia una singleton implementation in Java in contesti più avanzati.

Singleton e reflection

Un altro limite delle implementazioni classiche è la reflection. Anche se il costruttore è privato, la reflection può teoricamente forzarne l’accesso e creare una nuova istanza.

Per ridurre questo rischio, si può aggiungere un controllo nel costruttore:

public class ReflectionSafeSingleton {
 private static final ReflectionSafeSingleton INSTANCE = new ReflectionSafeSingleton();
 private ReflectionSafeSingleton() {
 if (INSTANCE != null) {
 throw new IllegalStateException("Singleton già inizializzato");
 }
 }
 public static ReflectionSafeSingleton getInstance() {
 return INSTANCE;
 }
}

Questa soluzione può aiutare, ma non risolve ogni scenario possibile. Anche per questo motivo, l’implementazione con enum è spesso considerata più robusta.

How to create Singleton Class in Java

Chi cerca how to create singleton class in Java o how to make singleton class in Java vuole spesso una risposta pratica e diretta.

Per creare una Singleton Class in Java bisogna seguire questi passaggi:

  • dichiarare la classe;

  • creare un campo statico per conservare l’unica istanza;

  • rendere privato il costruttore;

  • creare un metodo pubblico statico, di solito chiamato getInstance();

  • scegliere se l’inizializzazione deve essere eager o lazy;

  • valutare se l’applicazione è multithread;

  • proteggere la classe da problemi di serializzazione, se necessario.

Un esempio moderno e semplice è questo:

public class AppConfig {
 private AppConfig() {
 }
 private static class Holder {
 private static final AppConfig INSTANCE = new AppConfig();
 }
 public static AppConfig getInstance() {
 return Holder.INSTANCE;
 }
 public String getApplicationName() {
 return "JavaBoss";
 }
}

Utilizzo:

public class Main {
 public static void main(String[] args) {
 AppConfig config = AppConfig.getInstance();
 System.out.println(config.getApplicationName());
 }
}

Questo è un buon java singleton example perché è leggibile, lazy e thread safe.

Singleton Annotation Java

La ricerca singleton annotation Java può riferirsi a concetti diversi, quindi è importante fare chiarezza.

Nel Java puro non esiste un’annotazione standard universale chiamata semplicemente @Singleton da usare per trasformare automaticamente qualsiasi classe in un Singleton tradizionale.

Esistono però annotazioni legate a framework o specifiche.

In Jakarta EE, per esempio, esiste jakarta.ejb.Singleton, usata per definire un singleton session bean gestito dal container.

Esempio:

import jakarta.ejb.Singleton;
@Singleton
public class ApplicationCounter {
 private int counter;
 public int increment() {
 return ++counter;
 }
}

In questo caso non siamo davanti allo stesso Singleton manuale visto prima. L’istanza viene gestita dal container Jakarta EE, non direttamente dalla classe tramite un metodo getInstance().

Anche in Spring si parla spesso di singleton, ma il significato è diverso rispetto al design pattern classico.

Singleton in Spring

In Spring, lo scope singleton indica che il container Spring crea una sola istanza di un bean per ogni ApplicationContext.

Questo significa che, quando una classe viene gestita da Spring come bean singleton, tutte le richieste dello stesso bean ricevono la stessa istanza all’interno del container.

Esempio:

import org.springframework.stereotype.Service;
@Service
public class UserService {
 public void execute() {
 System.out.println("Servizio eseguito");
 }
}

In Spring, lo scope singleton è quello predefinito. Quindi, nella maggior parte dei casi, non è necessario specificarlo esplicitamente.

È comunque possibile usare @Scope("singleton"):

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
@Scope("singleton")
public class UserService {
}

La differenza principale è questa: il Singleton Pattern classico controlla l’istanza a livello di classe e spesso a livello di class loader, mentre il singleton di Spring è una singola istanza gestita dal container Spring all’interno di uno specifico ApplicationContext.

Quindi, quando si parla di singleton in Java e di singleton in Spring, non sempre si parla esattamente della stessa cosa.

Singleton Pattern Java e Dependency Injection

Con l’uso moderno di framework come Spring, Jakarta EE, Micronaut o Quarkus, spesso non è necessario implementare manualmente un Singleton.

In molte applicazioni enterprise, è preferibile lasciare che il container gestisca il ciclo di vita degli oggetti. Invece di chiamare direttamente MySingleton.getInstance(), si inietta una dipendenza.

Esempio con Spring:

@Service
public class NotificationService {
 public void send(String message) {
 System.out.println(message);
 }
}

E poi:

@Service
public class OrderService {
 private final NotificationService notificationService;
 public OrderService(NotificationService notificationService) {
 this.notificationService = notificationService;
 }
 public void createOrder() {
 notificationService.send("Ordine creato");
 }
}

Questo approccio è spesso più testabile, più flessibile e più adatto ad applicazioni moderne rispetto a un Singleton manuale con accesso globale.

Il Singleton classico rimane utile, ma deve essere scelto consapevolmente.

Java Singleton List

La keyword java singleton list può essere interpretata in due modi.

Il primo riguarda una lista gestita dentro un Singleton. Per esempio, una classe Singleton che conserva una lista globale di elementi.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Registry {
 private final List<String> items = new ArrayList<>();
 private Registry() {
 }
 private static class Holder {
 private static final Registry INSTANCE = new Registry();
 }
 public static Registry getInstance() {
 return Holder.INSTANCE;
 }
 public void addItem(String item) {
 items.add(item);
 }
 public List<String> getItems() {
 return Collections.unmodifiableList(items);
 }
}

In questo esempio, getItems() restituisce una lista non modificabile dall’esterno. Questo è importante perché esporre direttamente una lista interna mutabile può rompere l’incapsulamento.

Il secondo significato può riferirsi a liste singleton, cioè liste con un solo elemento. In Java, per esempio, è possibile usare:

List<String> list = Collections.singletonList("Java");

Oppure, nelle versioni moderne di Java:

List<String> list = List.of("Java");

Questi esempi non rappresentano il Singleton Pattern, ma strutture dati che contengono un solo elemento. È quindi importante non confondere una singleton class con una singleton list.

Differenza tra Singleton e classe statica

A prima vista, un Singleton può sembrare simile a una classe con soli metodi statici. In realtà, ci sono differenze importanti.

Una classe statica non viene istanziata e contiene metodi o variabili statiche. Un Singleton, invece, è un oggetto reale. Può implementare interfacce, può essere passato come dipendenza, può avere uno stato interno e può partecipare in modo più naturale a un modello orientato agli oggetti.

Esempio di classe statica:

public final class MathUtils {
 private MathUtils() {
 }
 public static int sum(int a, int b) {
 return a + b;
 }
}

Esempio di Singleton:

public class ConfigurationManager {
 private ConfigurationManager() {
 }
 private static class Holder {
 private static final ConfigurationManager INSTANCE = new ConfigurationManager();
 }
 public static ConfigurationManager getInstance() {
 return Holder.INSTANCE;
 }
}

Una classe statica è utile per funzioni pure e utility senza stato. Un Singleton è più adatto quando serve un oggetto unico con comportamento, stato controllato o ciclo di vita specifico.

Vantaggi del Singleton Design Pattern in Java

Il singleton design pattern in Java offre diversi vantaggi quando viene usato correttamente.

Permette di controllare la creazione dell’oggetto, evitando istanze multiple non necessarie. Offre un punto di accesso centralizzato. Può essere utile per gestire risorse condivise. Riduce la duplicazione in casi in cui avere più istanze sarebbe inutile o dannoso.

Inoltre, alcune implementazioni del Singleton sono semplici e leggibili, specialmente il Bill Pugh Singleton e l’Enum Singleton.

Il Singleton può anche essere utile per rappresentare componenti che, per natura, devono essere unici nel contesto dell’applicazione: un registro, una configurazione globale, un gestore di stato controllato o un servizio di basso livello.

Svantaggi del Singleton Pattern Java

Il Singleton ha anche diversi svantaggi.

Il primo è la presenza di stato globale. Un oggetto accessibile da qualsiasi punto dell’applicazione può rendere il codice meno prevedibile e più difficile da controllare.

Il secondo è la difficoltà nei test. Una classe che chiama direttamente Singleton.getInstance() è più difficile da testare rispetto a una classe che riceve le proprie dipendenze tramite costruttore.

Il terzo è il rischio di accoppiamento forte. Il codice può diventare dipendente da un’implementazione concreta invece che da un’interfaccia.

Il quarto è la falsa semplicità. Molti Singleton sembrano facili, ma diventano complicati quando entrano in gioco thread, serializzazione, reflection, class loader, framework, container e ambienti distribuiti.

Per questo motivo, il pattern Singleton Java deve essere usato con criterio.

Quando usare il Singleton in Java

Conviene usare un Singleton quando esiste una reale necessità di avere una sola istanza di una classe.

Può essere una buona scelta per oggetti immutabili, configurazioni lette una sola volta, componenti leggeri, registry interni, factory o servizi tecnici semplici.

È preferibile evitarlo quando l’oggetto contiene molto stato mutabile, quando deve essere facilmente sostituito nei test, quando l’applicazione usa già un framework di dependency injection o quando l’unicità deve essere garantita a livello distribuito tra più processi, server o nodi.

Un Singleton Java tradizionale garantisce una sola istanza all’interno di un certo contesto della JVM, ma non garantisce automaticamente una sola istanza in un cluster, in un sistema distribuito o in più applicazioni eseguite separatamente.

Migliore implementazione Singleton in Java

Non esiste una risposta unica valida per ogni progetto, ma si possono dare alcune indicazioni pratiche.

Per un Singleton semplice e robusto, l’implementazione con enum è spesso una delle migliori scelte.

public enum DatabaseConfig {
 INSTANCE;
 public String getUrl() {
 return "jdbc:mysql://localhost:3306/app";
 }
}

Per un Singleton lazy, leggibile e thread safe, il Bill Pugh Singleton è una scelta eccellente.

public class DatabaseConfig {
 private DatabaseConfig() {
 }
 private static class Holder {
 private static final DatabaseConfig INSTANCE = new DatabaseConfig();
 }
 public static DatabaseConfig getInstance() {
 return Holder.INSTANCE;
 }
}

Per un progetto Spring, spesso è meglio evitare il Singleton manuale e usare un bean gestito dal container.

@Service
public class DatabaseConfigService {
}

La scelta dipende dal contesto: Java puro, applicazione enterprise, framework, testabilità, serializzazione, performance e complessità del ciclo di vita.

Errori comuni nel Singleton Java

Uno degli errori più comuni è creare un Singleton non thread safe e usarlo in un’applicazione multithread.

Un altro errore è dimenticare volatile nel Double-Checked Locking.

Un altro ancora è usare il Singleton come contenitore globale di stato mutabile. Questo può creare bug difficili da individuare, soprattutto quando molte classi leggono e modificano lo stesso oggetto condiviso.

È anche sbagliato pensare che il Singleton sia sempre la soluzione migliore per “avere accesso facile” a un oggetto. Spesso, se il problema è passare dipendenze tra classi, la soluzione migliore è la dependency injection, non un Singleton globale.

Infine, bisogna fare attenzione a non confondere il Singleton Pattern con il singleton scope di Spring, con @Singleton di Jakarta EE o con una lista contenente un solo elemento.

Java Singletone

La forma java singletone è un errore di scrittura abbastanza comune. Il termine corretto è Java Singleton.

Anche se alcuni utenti cercano “singletone”, nel contesto tecnico corretto si parla di Singleton, Singleton Pattern, Singleton Design Pattern, Singleton Class o Singleton Implementation.

FAQ sul Java Singleton

Che cos’è un Java Singleton?

Un Java Singleton è una classe progettata per avere una sola istanza durante l’esecuzione dell’applicazione e per fornire un punto di accesso globale a tale istanza.

Cos’è il Singleton Pattern Java?

Il Singleton Pattern Java è un design pattern creazionale che limita la creazione di oggetti di una classe a una sola istanza.

Come creare una singleton class in Java?

Per creare una singleton class in Java bisogna rendere privato il costruttore, conservare una istanza statica e fornire un metodo pubblico statico, di solito getInstance(), per recuperare l’istanza.

Qual è un esempio di Singleton Pattern in Java?

Un esempio semplice è una classe AppConfig con costruttore privato, classe interna statica Holder e metodo getInstance() che restituisce l’unica istanza.

Il Singleton in Java è thread safe?

Dipende dall’implementazione. Un Singleton base con lazy initialization non è thread safe. Sono thread safe l’eager singleton, il metodo sincronizzato, il double-checked locking con volatile, il Bill Pugh Singleton e l’Enum Singleton.

Qual è la migliore singleton implementation in Java?

Per molti casi, le soluzioni migliori sono l’Enum Singleton e il Bill Pugh Singleton. Nei progetti Spring, spesso è preferibile usare un bean gestito dal container invece di un Singleton manuale.

Che differenza c’è tra Singleton Java e singleton Spring?

Il Singleton Java classico è un design pattern implementato nella classe. Il singleton Spring è uno scope del container: Spring crea una sola istanza del bean all’interno dell’ApplicationContext.

Esiste una singleton annotation Java?

Nel Java puro non esiste un’annotazione universale per creare automaticamente un Singleton classico. Esistono però annotazioni come jakarta.ejb.Singleton in Jakarta EE o configurazioni di scope in Spring.

Singleton e classe statica sono la stessa cosa?

No. Una classe statica contiene metodi statici e non viene istanziata. Un Singleton è un oggetto reale, può implementare interfacce, avere stato e partecipare meglio a un modello orientato agli oggetti.

Quando evitare il Singleton Pattern in Java?

È meglio evitarlo quando introduce stato globale mutabile, rende difficili i test, crea accoppiamento forte o viene usato solo per evitare una corretta gestione delle dipendenze.

Conclusione

Il Java Singleton è un pattern fondamentale per chi sviluppa in Java. È semplice da capire, ma richiede attenzione per essere implementato correttamente.

Il singleton pattern Java permette di garantire una sola istanza di una classe e di offrire un punto di accesso globale. Tuttavia, non tutte le implementazioni sono equivalenti. Una versione base può funzionare in single-thread, ma non è sufficiente in ambienti concorrenti. Per un java singleton thread safe, è necessario usare soluzioni come synchronized, Double-Checked Locking con volatile, Bill Pugh Singleton o Enum Singleton.

Nelle applicazioni moderne, soprattutto con Spring o Jakarta EE, è importante distinguere tra Singleton Pattern classico, singleton scope del container e annotazioni come @Singleton.

Il Singleton rimane uno strumento utile, ma deve essere usato solo quando esiste una reale necessità di avere una singola istanza condivisa. Se usato bene, rende il codice più ordinado e controllato. Se usato male, introduce dipendenze globali, problemi di testabilità e complessità nascosta.

Categorie: Java