Java: classe statica?


130

Ho una classe piena di funzioni di utilità. L'istanza di un'istanza non ha senso semantico, ma voglio ancora chiamarne i metodi. Qual è il modo migliore per affrontarlo? Classe statica? Astratto?


14
Non puoi rendere statica una classe di livello superiore ...
Jon

Risposte:


163

Costruttore privato e metodi statici su una classe contrassegnata come finale.


19
@matt b: come sottolinea David Robles nella sua risposta, non è necessario rendere la classe finale ... non può essere sottoclassata perché una sottoclasse non sarà in grado di invocare un costruttore di superclassi perché è privato. Tuttavia ... nessun danno nell'essere esplicito. Ma jfyi :-).
Tom,

93

Secondo il grande libro "Effective Java" :

Articolo 4: impone la non-affidabilità con un costruttore privato

- Il tentativo di imporre la non inaffidabilità facendo un abstract di classe non funziona.

- Un costruttore predefinito viene generato solo se una classe non contiene costruttori espliciti, quindi una classe può essere resa non sostanziale includendo un costruttore privato:

// Noninstantiable utility class
public class UtilityClass
{
    // Suppress default constructor for noninstantiability
    private UtilityClass() {
        throw new AssertionError();
    }
}

Poiché il costruttore esplicito è privato, è inaccessibile al di fuori della classe. AssertionError non è strettamente necessario, ma fornisce un'assicurazione nel caso in cui il costruttore venga accidentalmente invocato all'interno della classe. Garantisce che la classe non verrà mai istanziata in nessuna circostanza. Questo idioma è leggermente controintuitivo, poiché il costruttore viene fornito espressamente in modo che non possa essere invocato. È quindi consigliabile includere un commento, come mostrato sopra.

Come effetto collaterale, questo linguaggio impedisce anche che la classe venga sottoclassata. Tutti i costruttori devono invocare un costruttore di superclassi, esplicitamente o implicitamente, e una sottoclasse non avrebbe costruttori di superclassi accessibili da invocare.


1
Perché avete scelto AssertionErrorrispetto ad altre alternative come IllegalStateException, UnsupportedOperationException, ecc?
Pacerier,

@Pacerier Vedi questo .
bcsb1001,

@ bcsb1001, Questo ci porta a questo .
Pacerier,


6

Solo per nuotare a monte, i membri e le classi statici non partecipano a OO e sono quindi malvagi. No, non male, ma seriamente, consiglierei una lezione regolare con un modello singleton per l'accesso. In questo modo, se è necessario ignorare il comportamento in ogni caso lungo la strada, non è un ritocco importante. OO è tuo amico :-)

I miei $ 0,02


17
Anche i single sono considerati cattivi.
Dan Dyer,

3
Si utilizza il costruttore privato per impedire a chiunque di creare un'istanza o una sottoclasse della classe. Vedi la risposta di David Robles: stackoverflow.com/questions/1844355/java-static-class/…
rob

5
singleton non è più malvagio dell'iniezione di dipendenza :)
indiscutibile il

12
OO ha il suo posto, ma ci sono momenti in cui semplicemente non è pratico, o sarebbe uno spreco di risorse, ad esempio qualcosa di semplice come Math.abs (). Non c'è motivo di creare un'istanza di un oggetto solo per l'istanza di un oggetto, quando una chiamata di metodo statico ti avrebbe servito altrettanto bene senza alcun sovraccarico di OO. ;)
rob

2
@rob re OO, sono d'accordo, Math.Abs ​​probabilmente non ha mai bisogno di un'istanza. Quando sento "Ho una classe di utilità", vedo Math.Avg (), dove ora è necessario aggiungere il supporto per una media ponderata. Vedo un generatore di URL, param in, url out che deve essere refactored per supportare href, o solo url, ecc. Ecc. Per questi motivi, avere la classe di utilità basata su OO può ripagare. Inoltre, ora lascerò cadere la tattica difensiva OO standard, test! / me ducks
Bennett Dill il

3

commenta gli argomenti del "costruttore privato": dai, gli sviluppatori non sono così stupidi; ma sono pigri. creazione di un oggetto quindi chiamare metodi statici? non succederà.

non perdere troppo tempo per assicurarti che la tua classe non possa essere utilizzata in modo improprio. abbi un po 'di fiducia per i tuoi colleghi. e c'è sempre un modo per abusare della tua classe, indipendentemente da come la proteggi. l'unica cosa che non può essere utilizzata in modo improprio è una cosa completamente inutile.


7
Qualcuno che ha visto (nel codice di produzione, non nel codice dello studente jsut) object.staticMethod Penso che tu sopravvaluti le capacità di Joe Random Programmer! :-P
TofuBeer,

2
  • Classe finale e costruttore privato (buono ma non essenziale)
  • Metodi statici pubblici

1

Non ha senso dichiarare la classe come static. Dichiara semplicemente i suoi metodi statice chiamali come normali dal nome della classe, come la classe Math di Java .

Inoltre, anche se non è strettamente necessario rendere privato il costruttore, è una buona idea farlo. Contrassegnare il costruttore come privato impedisce ad altre persone di creare istanze della classe, quindi chiamare metodi statici da tali istanze. (Queste chiamate funzionano esattamente allo stesso modo in Java, sono solo fuorvianti e danneggiano la leggibilità del tuo codice.)


1
Inoltre, non dimenticare di creare un costruttore privato.
Asaph,

@Asaph: concordato. Ho aggiunto un po 'di questo alla mia risposta. Grazie.
Bill the Lizard,

Se desideri metodi statici all'interno di una classe interna, anche la classe deve essere statica.
Rui Marques,

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.