2010-01-17 15 views
46

Ho letto che Java non supporta le variabili locali static diversamente da C/C++. Ora se voglio codificare una funzione con una variabile locale, il cui valore dovrebbe persistere tra le chiamate di funzione, come posso farlo?
Dovrei ricorrere all'utilizzo di variabili di istanza?Come posso creare una variabile locale statica in Java?

+0

questo è il motivo per cui Java ha bisogno di chiusure (scherzando). –

+0

@darren: cosa devono fare le chiusure con i locals statici? – missingfaktor

+9

voleva che i locals statici (in senso C) mantenessero lo stato attraverso chiamate a funzioni multiple. In altre parole, la gente del posto esiste dopo il ritorno della funzione. Questo è un uso delle chiusure. –

risposta

29

È possibile avere una variabile di classe statica, che verrà mantenuta in tutte le istanze della classe. Se questo è quello che vuoi. In caso contrario, utilizzare una variabile di istanza, che verrà conservata solo attraverso le chiamate di metodo su questo oggetto.

public class Foo { 
    static int bar; 
    //set bar somewhere 

    public int baz() { 
     return 3 * bar; 
    } 
} 
+7

Penso che nella maggior parte dei casi * le variabili d'istanza * dovrebbero andare bene, se quello che @gameover vuole è qualcosa per sostituire le variabili locali statiche del metodo. – bryantsai

+0

Sono d'accordo. È piuttosto raro voler una variabile statica non finale. L'assegnazione di numeri ID agli oggetti è un esempio, tuttavia: memorizza l'ultimo numero ID utilizzato come variabile statica. assignID() restituisce lastID + 1 –

+5

@EllieP. 'return lastID ++;' – Cruncher

4

Should I resort to using instance variables?

sì - dopo tutto, questo è ciò che le variabili di istanza sono per. Memorizzano lo stato tra le invocazioni dei metodi dell'oggetto. Avere variabili di classe statiche può raggiungere lo stesso risultato, ma può rendere il tuo programma più accoppiato e più difficile da testare/simulare/mantenere.

4

Se si desidera riutilizzare il valore della variabile tra chiamate di funzione e isolare questa variabile da altri metodi, si dovrebbe incapsulare in un oggetto. In primo luogo, definire una classe con solo le variabili "statiche-like" e la funzione è necessario:

class MyFunctionWithState { 
    private int myVar = 0; 
    public int call() { 
     myVar++; 
     return myVar; 
    } 
} 

Poi, dal codice client:

class Foo { 
    private MyFunctionWithState func = new MyFunctionWithState(); 
    public int bar() { 
     return func.call(); 
    } 
} 

Ora, se func si basa sullo stato interno del Foo è possibile passare i dati rilevanti attraverso call() o passare un'istanza di Foo e lasciare che la funzione di chiamare i getter appropriate:

class MyFunctionWithState { 
    private int myVar = 0; 
    public int call(Foo f) { 
     myVar += f.getBaz(); 
     return myVar; 
    } 
} 

class Foo { 
    private MyFunctionWithState func = new MyFunctionWithState(); 
    public int bar() { 
     return func.call(this); 
    } 
    public int getBaz() { /*...*/ } 
} 
+0

Perché deve essere così complicato? Il posizionamento di static int myVar in una funzione membro è in conflitto con una parte della lingua o funzionalità java? Non sono d'accordo che sia raro volere qualcosa di questo tipo. Forse ho bisogno di qualche funzione per mantenere lo stato di una variabile e non voglio che tutte le altre funzioni all'interno della classe abbiano accesso a quella variabile. È molto meglio avere la variabile più vicina a dove viene usata. Immagino che potrei posizionare la variabile proprio sopra la funzione, ma ciò consente comunque di creare confusione quando altre funzioni potrebbero usare lo stesso nome di variabile. – user1164199

+0

Quando ho detto "Il posizionamento statico di myVar in una funzione membro è in conflitto con una parte della lingua o della funzione java?", Intendevo "sarebbe possibile aggiungere questa funzione di lingua in una versione futura di java?" – user1164199

5

Le variabili locali sono variabili all'interno di un metodo. Solo il metodo ottiene l'accesso a queste variabili. non puoi avere una variabile locale statica, ma puoi usare variabili di istanza o variabili di classe.

Se il metodo è statico, per impostazione predefinita crea una copia di questo metodo su tutti gli oggetti e non può essere ulteriormente scomposto in quanto le variabili locali limitano il loro accesso solo al metodo in cui risiedono.

-3

final int intVar = 1; // Verranno inseriti solo una volta. Si comporta come var locale statica C++ nel metodo.

+2

Questa è una risposta fuorviante, poiché l'unico motivo per cui intVar si comporta come una variabile locale statica C++ in questo esempio è perché è assegnata una costante. per esempio. nel metodo 'void (int arg) {final int intVar = arg; ...} ',' intVar' non si comporta come una variabile locale statica C++. –

+0

non è possibile incrementare o decrementare le variabili finali –

-1

Nell'esempio seguente count si comporta come una variabile statica locale, che si potrebbe utilizzare in C:

public class Foo { 

    private int count = 0; 

    public int getCount() { 
     return count++;    
    } 
} 

ci sono statici locali variabili come il supporto di altre lingue. Poiché java è molto orientato alla "classe", cerca di portarlo in quel contesto. Se si desidera simulare tale comportamento, si utilizza una variabile di istanza, che viene utilizzata solo da questo metodo. Quindi questo è statico per le chiamate del metodo diverse, non per la classe stessa.

+1

Statico per una singola istanza non mi sembra molto statico. Il punto principale di staticità è A) valore globale nella classe. Non dipende dall'istanza. B) Evitare di creare una variabile per ogni istanza :) – borjab

+0

@borjab: Vero, ma poiché l'OP ha scritto: 'Ora se voglio codificare una funzione con una variabile locale, il cui valore dovrebbe persistere tra le chiamate di funzione, come faccio? ? '... sembrava giusto rispondere con l'ovvio. Statico dipende in qualche modo dal contesto: per la funzione all'interno di questa istanza sarebbe 'statico' ... d'altra parte le normali classi' static' non sono molto statiche tra le diverse istanze del programma o anche dispositivi diversi ;-) – Levit

0

O hai contrassegnato una risposta corretta che non era, o in realtà volevi variabili di classe statiche - ma la risposta corretta è fondamentalmente quella di Levit, o tecnicamente una miscela di tutte le risposte.

Per le persone provenienti da uno sfondo C come me, che desiderano veramente le variabili locali di funzione statica puramente per il vantaggio dell'ambito rispetto ai globali, sembra che la risposta non sia possibile in Java.Non senza fare qualcosa come @paradigmatic sta andando con un'istanza di una classe con un globale statico e getter() univoco per l'istanza della classe in cui si esegue la funzione.

Se, come sospetto, si ' ri eseguendo la classe come un Singleton, o completamente staticamente come il programmatore procedurale inziale che abbiamo iniziato, la risposta di @Ellie P's o @ user2626445 funzionerebbe bene poiché nessun'altra istanza rovinerebbe il tuo globale. Ma per ottenere quello che penso che vuoi, dovrebbe essere solo una variabile di istanza, che è globale in C. Persistono tra le chiamate di funzione ma consentono di utilizzare la tua funzione in modo OO, quindi più istanze possono mantenere le proprie variabili persistenti per questa particolare funzione.

Personalmente, mi aggiro in questo modo in jave nello stesso modo in cui giro Hi-Tech C non permettendo le variabili bit di funzione, dichiarando il globale nel file appena sopra la dichiarazione di funzione. In questo modo, quando indago il codice in seguito, è meno probabile pensare che sia globale e sia tentato di scherzare con esso - non è per questo che incapsuliamo le cose?

Problemi correlati