2012-10-23 9 views
17

Un interno classe definito all'interno di un metodo non può accedere alle variabili locali del metodo a meno che queste variabili locali non siano contrassegnate final. Ho esaminato altri post nello stack overflow e nel java code ranch ma nessuno di essi sembra rispondere esattamente al domanda su come la marcatura delle variabili finali permette alla classe interna di accedere alle variabili locali nel metodo.In che modo contrassegnare una variabile come finale consente alle classi interne di accedervi?

class MyOuter { 
    private String x = "Outer"; 

    void fly(final int speed) { 
     final int e = 1; 
     class FlyingEquation { 

      public void seeOuter() 
      { 
       System.out.println("Outer x is " + x); 
      } 
      public void display() 
      { 
       System.out.println(e);// line 1 
       System.out.println(speed);// line 2 
      } 
     } 
     FlyingEquation f=new FlyingEquation(); 
     f.seeOuter(); 
     f.display(); 
    }  
    public static void main(String args[]) 
    { 
     MyOuter mo=new MyOuter(); 
     mo.fly(5); 
    } 
} 

Spiegazioni ho trovato a questo: le variabili

locali vengono memorizzate su stack e, non appena la chiamata al metodo termina la pila è spuntato e variabili locali inaccessibili mentre variabili locali finali sono memorizzati nella sezione dati della memoria consentendo potenzialmente di accedere a JVM anche dopo la fine della chiamata al metodo. Dov'è il data section of memory? Credo che tutte le variabili locali definitive o non siano memorizzate nello stack. Quando il metodo viene rimosso dallo stack, la variabile finale verrà rimossa con esso. È che il valore nella variabile finale è memorizzato con l'oggetto nell'heap?

Non supporta i campi non finali in quanto potrebbero essere modificati, sia dal metodo o dalla classe e questo non è supportato perché in realtà ci sono due diversi campi/variabili.

+0

Questo [SO link] (http://stackoverflow.com/a/1299889/1168372) potrebbe essere utile – Sujay

+0

ho aggiunto una risposta. Spero che ti abbia aiutato a leggere la mia risposta –

risposta

11

Durante l'istanziazione della classe interna, quando sia il metodo che la classe sono nell'ambito, la classe interna eseguirà una copia delle variabili che sono costanti, il che significa che il metodo può andare fuori dall'ambito, poiché l'interno la classe sta usando solo una copia della variabile. Check out this article.

13

Contrassegnare una variabile locale come final indica al compilatore che è garantito che il valore non venga modificato una volta assegnato. Ciò consente al compilatore di creare un campo sintetico all'interno della classe interna e copia copia il valore della variabile locale in questo campo sintetico quando viene creata l'istanza della classe interna. Tutte le letture della variabile locale dall'interno del codice di classe interno si compilano invece in letture del campo sintetico.

Questo trucco non funzionerebbe per variabili non definitive in quanto potrebbero cambiare dopo che la classe interna è stata istanziata e il campo sintetico non sarebbe sincronizzato con la variabile originale.

E 'importante rendersi conto che tutte le classi interne sono trucchi del compilatore - alla JVM runtime tutte le classi (di livello superiore, innestata statica, e interno) sono trattati allo stesso.

2

Sì, le variabili locali finali vengono salvate nello stack e vengono distrutte nel momento in cui il metodo viene rimosso dallo stack. Come suggerito da @Ian, quando il compilatore vede la parola chiave finale per la variabile, crea una copia del valore nell'oggetto di classe interna sull'heap.

0

La storia dietro questo è che i creatori di Java non hanno avuto abbastanza tempo per dare pieno supporto allo closure.

Ci sono diversi modi per rendere la chiusura del supporto linguistico. Ad esempio, nello schema, i parametri liberi in una funzione sono associati a un ambiente che corrisponde all'ambito lessicale in cui è definita la funzione.In un linguaggio che forza dati immutabili come SML, la chiusura può essere implementata copiando le variabili locali che sono necessarie dalla chiusura allo heap.

Così creano classe interiore per avere una versione di chiusura di un uomo povero che imita lo stile di ML.

0

Metodo Le classi interne locali non possono utilizzare la variabile locale del metodo esterno finché tale variabile locale non è dichiarata come finale. Il motivo principale per cui è necessario dichiarare una variabile locale come finale è che la variabile locale risiede nello stack finché il metodo non è nello stack ma potrebbe esserci un caso in cui l'oggetto della classe interna risiede ancora nell'heap.

checkout questo articolo: http://www.geeksforgeeks.org/inner-class-java/

0

Così ora pensare it.the variabili locali del metodo dal vivo nei pila ed esistono solo per la durata del metodo. Sappiamo già che l'ambito di una variabile locale è limitato al metodo in cui la variabile è dichiarata. Quando il metodo termina, il frame dello stack viene spazzato via e la variabile è history. Ma anche dopo il completamento del metodo, l'oggetto classe interna creato al suo interno potrebbe essere ancora vivo nell'heap se, per esempio, un riferimento ad esso è stato passato in qualche altro codice e quindi memorizzato in una variabile di istanza. Poiché le variabili locali non sono garantite come vere finché il metodo è l'oggetto locale della classe interna, l'oggetto della classe interna non può usarle. A meno che le variabili locali non siano contrassegnate con finale.

Vuol variabili locali finali vengono memorizzati su un mucchio invece di pila ?

Spiegazione: Ora, dopo qualche ricerca in SO ho scoperto che tutte le variabili locali (definitiva o meno) memorizzato nella pila e uscire del campo di applicazione quando l'esecuzione metodo è finita.

Tuttavia, la variabile finale è considerata come una costante in quanto non cambierà dopo l'avvio di . E quando una classe interna tenta di accedervi compilatore creare una copia di tale variabile (non che sé variabile) nella mucchio e creano un campo sinteticoall'interno della classe interna, quindi anche quando all'esecuzione metodo è è accessibile perché la classe interna ha la propria copia. Il campo sintetico è archiviato, che in realtà non esiste nel codice sorgente, ma il compilatore crea quei campi in alcune classi interne per renderli accessibili. Nella parola semplice nascosta il campo .

Quindi la variabile finale viene anche memorizzata nello stack ma la copia di quella variabile che una classe interna ha memorizzato nell'heap.

+0

:(?? –

Problemi correlati