2010-10-18 14 views
12

Come e dove dovremmo usare un modificatore statico per:Come e dove usare il modificatore statico in Java?

1. Campo e
2. Metodo?

Per example in java.lang.Math di classe, i metodi di campi come abs(), atan(), cos() ecc sono statici, cioè esse si può accedere come: Math.abs()

Ma perché è una buona pratica?

Dire, non lo mantengo statico e creare un oggetto della classe e accedervi, che comunque posso, ricevo solo un avvertimento che stai provando ad accedere a un metodo statico in modo non statico (come sottolineato da @duffymo, non nel caso della classe Math).

UPDATE 1:

Quindi, metodo di utilità, dovrebbe essere statico, cioè il cui lavoro dipende solo sui parametri di metodo. Quindi, ad esempio, il metodo updateString(String inputQuery, String highlightDoc) dovrebbe essere un metodo statico in this question?

risposta

20

Si può pensare a un metodo o campo "statico" come se fosse dichiarato al di fuori della definizione della classe. In altre parole

  1. C'è solo una "copia" di un campo/metodo statico.
  2. I campi/metodi statici non possono accedere a campi/metodi non statici.

Ci sono diversi casi in cui si vorrebbe creare qualcosa di statico.

L'esempio canonico per un campo consiste nel creare un campo intero statico che mantiene un conteggio attraverso tutte le istanze (oggetti) di una classe. Inoltre, ad esempio, gli oggetti singleton, in genere, utilizzano anche il modificatore statico.

Analogamente, i metodi statici possono essere utilizzati per eseguire lavori "di utilità" per cui tutte le dipendenze richieste vengono passate come parametri al metodo - non è possibile fare riferimento alla parola chiave "this" all'interno di un metodo statico.

In C#, si può anche avere classi statiche, che, come si può immaginare, contengono solo i membri statici:

public static class MyContainer 
{ 
    private static int _myStatic; 

    public static void PrintMe(string someString) 
    { 
     Console.Out.WriteLine(someString); 
     _myStatic++; 
    } 

    public static int PrintedInstances() 
    { 
     return _myStatic; 
    } 
} 
+0

si prega di controllare il mio aggiornamento. Puoi dare alcune informazioni sul metodo di esempio che ho postato nella mia domanda. Che è anche un metodo di utilità – zengr

+0

@zengr: Sì, vorrei rendere statico quel metodo. È possibile immaginare, ad esempio, una classe StringHelper che racchiuda tutte le operazioni di manipolazione delle stringhe specifiche dell'applicazione (come quella eseguita da tale metodo). In effetti, vorrei rendere _any_ metodo statico se non fa riferimento alla parola chiave 'this'; non c'è bisogno di creare una copia di questo metodo su ogni oggetto, è più leggibile in questo modo, ed è buono per la chiarezza del design complessivo IMO. – Alex

1

Di solito, quando il metodo dipende solo i parametri della funzione e non sullo stato interno del oggetto è un metodo statico (con singletone è l'unica eccezione). Non riesco a immaginare dove i campi statici siano realmente usati (sono uguali alle variabili globali che dovrebbero essere evitate).
Come nell'esempio, le funzioni matematiche dipendono solo dai parametri.

+1

Ci sono usi perfettamente legittimi per il modificatore statico, come quelli elencati nella mia risposta. – Alex

+0

"sono le stesse delle variabili globali che dovrebbero essere evitate" - non se sono definitive; quelli appaiono spesso come costanti di classe. –

+0

@alex Non ci ho pensato. Immagino che l'uso di campi statici dipenda in gran parte dal tuo modo di programmare e probabilmente ci sono situazioni perfette quando usarli (e che non sono in alcun modo singletonone). Solo perché non li ho ancora visti non vuol dire che esistano o siano cattivi :) Per il mio stesso interesse, potresti spiegarmi perché vorresti conoscere il numero totale di istanze di un oggetto ma nessun riferimento ad esso? – Fge

0

Non è possibile creare un'istanza di java.lang.Math; non c'è un costruttore pubblico.

Provalo:

public class MathTest 
{ 
    public static void main(String [] args) 
    { 
     Math math = new Math(); 

     System.out.println("math.sqrt(2) = " + math.sqrt(2)); 
    } 
} 

Ecco cosa si ottiene:

C:\Documents and Settings\Michael\My Documents\MathTest.java:5: Math() has private access in java.lang.Math 
     Math math = new Math(); 
        ^
1 error 

Tool completed with exit code 1 
+0

Oops, mancato. Ma in generale, se un metodo è statico, possiamo comunque accedervi usando un oggetto. Quindi, da dove viene l'efficienza della memoria usando l'elettricità statica? – zengr

+1

Non è questione di efficienza della memoria; si tratta dell'intento del progettista di classe. – duffymo

1

Per un campo che si dovrebbe tenere statico se si desidera che tutte le istanze di una determinata classe di avere accesso al suo valore. Per esempio se ho

public static int age = 25; 

allora qualsiasi istanza della classe può ottenere o impostare il valore di età con tutta indicando lo stesso valore. Se si crea qualcosa di statico, si corre il rischio di avere due istanze che sovrascrivono reciprocamente i valori e che potrebbero causare problemi.

Il motivo per creare metodi statici è principalmente per la funzione di utilità in cui vengono passati tutti i dati necessari per il metodo e non si desidera prendere in carico la creazione di un'istanza della classe ogni volta che si desidera chiamare il metodo.

8

Statico utilizza meno memoria poiché esiste solo una volta per Classloader.

Per avere metodi statici si può risparmiare un po 'di tempo, perché non è necessario creare prima un oggetto per poter chiamare una funzione. Puoi/dovresti usare i metodi statici quando stanno praticamente da soli (per esempio Math.abs (X) - non c'è davvero alcun oggetto di cui la funzione abbia bisogno.) Fondamentalmente è una cosa di convenienza (almeno per quello che vedo io - altri potrebbero e non saranno d'accordo: P)

I campi statici dovrebbero essere utilizzati con cautela. Ci sono alcuni modelli che richiedono campi statici ... ma le basi prima:

un campo statico esiste solo una volta. Quindi, se si dispone di una semplice classe (kinda pseudocodice):

class Simple { 
static int a; 
int b; 
} 

e ora si fanno oggetti con:

Simple myA = new Simple(); 
Simple myB = new Simple(); 
myA.a = 1; 
myA.b = 2; 
myB.a = 3; 
myB.b = 4; 
System.out.println(myA.a + myA.b + myB.a + myB.b); 

otterrete 3234 - perché impostando myB.a effettivamente sovrascrivere myA.a anche perché a è statico. Esiste in un posto nella memoria.

Normalmente si vuole evitare questo perché potrebbero accadere cose davvero strane. Ma se ad esempio google per Modello di fabbrica vedrai che ci sono degli usi davvero utili per questo comportamento.

Spero che si risolva un po '.

+1

I campi statici esistono una volta per caricatore di classi, non una sola volta per JVM. – user82928

2

Prova a dare un'occhiata a questo post, fornisce anche alcuni esempi su quando e quando non utilizzare i modificatori statici e finali.

La maggior parte dei post precedenti sono simili, ma questo post potrebbe offrire qualche altro approfondimento.
When to use Static Modifiers

Problemi correlati