HOWTO · Java
Classe statica in Java
Questo articolo introduce le classi statiche Java.
In questa pagina
In Java una classe di primo livello non può essere dichiarata static. Una classe dichiarata all’interno di un’altra classe, invece, può essere static: in questo caso si parla di classe annidata statica. È possibile istanziarla senza creare un’istanza della classe che la racchiude e può accedere ai membri statici di quest’ultima. Se vuoi una classe di utilità che i chiamanti non possano istanziare tramite la sua API pubblica, usa invece un costruttore privato: è un modello di progettazione distinto.
Che cos’è una classe annidata statica in Java?
Una classe annidata statica è un tipo membro dichiarato con la parola chiave static all’interno di un’altra classe. Il modificatore static indica che un’istanza della classe annidata non ha un riferimento implicito a un oggetto della classe che la racchiude. Non significa che la classe annidata non possa essere istanziata. Il suo tipo si richiama tramite il tipo contenitore, per esempio Container.Entry, mentre un metodo di istanza si chiama su un’istanza di quel tipo annidato.
Una classe annidata statica può accedere ai membri statici della classe che la racchiude, compresi quelli privati. Non può fare riferimento ai campi o ai metodi di un’istanza della classe contenitore come se disponesse di quell’istanza. Può farlo se le viene fornito esplicitamente un oggetto della classe contenitore.
Come dichiarare e usare una classe annidata statica
Dichiara la classe membro con static, poi usa il nome del tipo contenitore per crearne un’istanza. Questo esempio completo mostra anche come accedere a un campo statico della classe contenitore:
Esegui questo esempio:
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
public class Container {
private static int count = 3;
public static class Entry {
public int value() {
return count;
}
}
public static void main(String[] args) {
Container.Entry entry = new Container.Entry();
System.out.println(entry.value());
}
}
3
L’esempio stampa 3. Quando lo adatti, mantieni la classe annidata all’interno della classe contenitore e, al di fuori di Container, qualificala con il tipo Container.Entry. L’oggetto Entry è una normale istanza, mentre count appartiene alla classe contenitore stessa.
Classe annidata statica e classe interna a confronto
Una classe membro non statica è comunemente chiamata classe interna. Per crearne un’istanza serve un’istanza della classe contenitore: crea un oggetto Container, poi usa container.new Inner(). Un’istanza della classe interna può accedere direttamente ai membri di istanza dell’oggetto contenitore, perché mantiene questo legame.
Una classe annidata statica non ha questo legame implicito. Per leggere un campo di un’istanza contenitore, passa o procurati in altro modo un oggetto Container e accedi al campo tramite quel riferimento. Entrambi i tipi di classi annidate possono accedere ai membri consentiti dalle regole di accesso di Java per i tipi annidati; la differenza fondamentale è che solo la classe interna dispone automaticamente di un’istanza contenitore.
Come creare una classe di utilità non istanziabile
Una classe di utilità raccoglie operazioni o costanti che non richiedono uno stato specifico per ogni oggetto. Inserisci questi membri in una normale classe di primo livello, contrassegna con static quelli appropriati e aggiungi un costruttore privato, dichiarato con private, così che i normali chiamanti non possano invocare new dall’esterno della classe. Per esempio, il modello è public final class TextTools { private TextTools() {} public static String join(String first, String second) { return first + second; } }; la chiamata è TextTools.join("static ", "utility").
Il costruttore privato impedisce la normale creazione di istanze dall’esterno, ma non trasforma TextTools in una classe statica: Java non ammette classi di primo livello statiche. Dichiarare la classe final è facoltativo e impedisce soltanto di estenderla. Usalo quando questa limitazione fa parte del progetto, non perché sia necessario per i metodi di utilità.
Idee errate comuni sulle classi statiche
Una classe annidata statica può essere istanziata: static elimina il requisito di un’istanza contenitore implicita. I suoi metodi di istanza possono usare i campi della propria istanza. Il nome della classe contenitore qualifica il tipo annidato, ma per chiamarne i metodi di istanza serve comunque un oggetto di quel tipo.
Un contesto statico non può accedere a un membro di istanza della classe contenitore usando un nome non qualificato, perché non dispone automaticamente di un oggetto contenitore. Può accedere a quel membro tramite un riferimento esplicito a un oggetto. Allo stesso modo, un costruttore privato di una classe di utilità impedisce le normali chiamate dall’esterno della classe, ma non rende impossibile la creazione di istanze in qualsiasi circostanza. Queste distinzioni separano la sintassi delle classi annidate di Java dal modello delle classi di utilità.