2013-08-14 19 views
31

Mi chiedevo se fosse possibile utilizzare le variabili locali finali. Le variabili non vengono comunque sovrascritte quando l'ereditarietà entra in scena. Per esempio un semplice codice come sottoUso di variabili locali finali in java

public static void main(String args[]) { 
    final String data = "Hello World!"; 
    System.out.println(data); 
} 

L'esempio è molto semplice e non può essere un codice corrispondente, ma la questione è più generic.I hanno visto un sacco di codici (tutti incorporati nella funzione principale che ha finale variabili locali) Esiste l'usabilità di dichiarare variabili locali come finali diverse da quelle che non possono essere modificate nella stessa funzione stessa?

+0

perché ne hai bisogno? puoi usarlo con codifica hard o avere una finale privata nella classe –

risposta

57

In primo luogo, la parte sulle variabili essendo "override" - final ha due significati molto diversi. Per classi e metodi, riguarda l'ereditarietà; per le variabili si tratta di essere di sola lettura.

C'è un importante "caratteristica" di variabili locali finali: possono essere utilizzati in genere (anonimi) le classi interne locali. Le variabili locali non finali non possono essere. Questo è l'uso principale di final per le variabili locali, nella mia esperienza.

public void foo() { 
    final String x = "hello"; 
    String y = "there"; 

    Runnable runnable = new Runnable() { 
     @Override public void run() { 
      System.out.println(x); // This is valid 
      System.out.println(y); // This is not 
     } 
    }; 
    runnable.run(); 
} 

Si noti che per una questione di stile, alcune persone piace usare final anche quando sono non catturare la variabile in una classe interna locale. Sarei certamente a mio agio con final come predefinito, ma con un diverso modificatore per "non-finale", ma trovo che aggiungere il modificatore esplicitamente ovunque sia troppo fastidioso.

+0

Inoltre, mi sembra utile per l'ottimizzazione. Poiché il valore di questa variabile finale non cambierà, JVM memorizzerà nella cache il valore di questa variabile per migliorare le prestazioni. –

+9

@Ankur che non è stato il caso per molto tempo. Il compilatore può facilmente risolvere se una variabile viene modificata o meno e ottimizzare di conseguenza. Ecco [un'altra risposta SO] (http://stackoverflow.com/a/4279442/2071828) a tale scopo. –

+2

@Jon Skeet È corretto supporre che queste variabili vadano al di là del loro ambito locale poiché possono accedere a classi interne anonime? – Ahmed

9

variabili locali finali possono accedere da sottoclassi interne anonime, mentre le variabili locali non finali non possono.

5

Sì, c'è, un piccolo expample dove potevamo normalmente usarlo -

Snippet:

final Boolean data = Boolean.TRUE; 
button.addListener(SWT.Selection, new Listener() { 
    public void handleEvent(Event event) { 
     if (data) { 
        .... 
       } 
     } 
}); 

E 'un esempio di utilizzo con le classi interne anonime. Se si desidera utilizzare la variabile locale all'interno di calss interno, è necessario effettuare final.

8

Sì, l'usabilità è: - la variabile finale locale è accessibile tramite la classe interna del metodo. Poiché le variabili locali vivono nello stack ed esistono solo per la durata del metodo, ma l'oggetto della classe Inner potrebbe vivere più a lungo in modo che la classe interna non possa accedere a nessuna variabile locale non finale. Ma una volta che la variabile è definitiva, la classe interna è sicura che il valore non cambierà in modo da mantenere una copia privata della variabile locale finale da utilizzare.

+0

Questa è l'unica risposta che ho trovato essere qualcosa di abbastanza appropriato .. bravo uno @ Krushna – DJphy

3

Si potrebbe utilizzare final parola chiave per migliorare la leggibilità e la garanzia non viene modificato o in classi anonime come qui:

final String s = "hi"; 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      // can use s variable here 
     } 
    }).start(); 
3

Racconta gli altri programmatori che chi ha scritto sapeva che il valore dei dati shouldn' t cambia una volta assegnato. È una buona abitudine, a mio parere, in particolare dichiarando le variabili dei parametri come finale.

5

Risposta perfetta Jon Skeet ma c'è un altro (piccolo) vantaggio delle variabili finali.

Il compilatore garantirà che la variabile finale sia impostata una sola volta e una sola volta.

Supponiamo di dover inizializzare una variabile e il calcolo del valore è complesso (più se-allora-altro all'interno di if-then-else). Potresti scrivere un codice che non inizializza la variabile in alcune condizioni (o inizializza due volte). Certo, questo è un bug. Rendere la variabile definitiva permetterà al compilatore di controllare che la variabile finale sia impostata una sola volta e una sola volta. Quindi saprai velocemente se hai un bug.

Come ho detto, piccolo vantaggio ma ancora a portata di mano.

4

L'utilizzo di variabili locali finali in java

final campi, i parametri e le variabili locali sono sola lettura (significa l'identità dell'oggetto, non il suo stato).

+0

Certo, ma qualsiasi compilatore degno di questo nome riconoscerà che la variabile non cambia mai all'interno del metodo e lo tratta esattamente come se fosse stato dichiarato finale. Gli unici vantaggi sono: qualcuno che legge o modifica il codice conoscerà l'intento dell'autore e ti impedisce di riassegnare per errore il valore. –

Problemi correlati