2012-04-26 12 views
14

Perché devo dichiarare un local variable come final se il mio Inner class definito all'interno del metodo deve utilizzarlo?Variabili della classe interna e locali

Esempio:

class MyOuter2 { 

private String x = "Outer2"; 

void doStuff() { 
    final String y = "Hello World"; 

    final class MyInner { 

     String z = y; 

     public void seeOuter() { 
      System.out.println("Outer x is "+x); 
      System.out.println("Local variable is "+y); 
      MyInner mi = new MyInner(); 
      mi.seeOuter(); 
     } 
    } 
} 

}

Perché la stringa y deve essere una costante finale? Come influisce?

+0

vedere se questa discussione aiuta http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/ – kosa

+0

possibile duplicato di [Impossibile riferirsi a una variabile non finale all'interno una classe interna definita in un metodo diverso] (http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a- differen) –

+0

[Domanda sulla variabile finale locale in Java] (http://stackoverflow.com/questions/5947352/question-about-local-final-variable-in-java). – Lion

risposta

13

La risposta è che i due sono in ambiti diversi. Quindi quella variabile potrebbe cambiare prima che la classe interna acceda a essa. Rendendolo definitivo lo impedisce.

+2

Questo è cambiato in java 8: http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html#accessing-members-of-an-enclosing-class – ohcibi

3

Penso che ciò impedisca al programmatore di commettere errori. In questo modo, il compilatore ricorda al programmatore che la variabile non sarà più accessibile quando lasci quel metodo. Questo è fondamentale con il loop. Immaginate questo codice:

public void doStuff() 
{ 
    InnerClass cls[] = new InnerClass[100]; 
    for (int i = 0; i < 100; ++i) 
    { 
     cls[i] = new InnerClass() 
     { 
      void doIt() 
      { 
       System.out.println(i); 
      } 
     }; 
    } 
} 

Quando il metodo doIt() viene chiamato, ciò che verrà stampato? i modificato durante il ciclo. Per evitare questa confusione, è necessario copiare la variabile in una variabile locale o creare la variabile finale, ma non sarà possibile eseguire il ciclo.

1

La tua classe interiore è definitiva e quindi non dovresti essere in grado di modificare nulla dall'interno della tua entità finale.

15

Le variabili locali vivono sempre in pila, il metodo momento è finito tutte le variabili locali sono sparite.

Ma gli oggetti della classe interna potrebbero trovarsi in heap anche dopo che il metodo è terminato (Supponiamo che una variabile di istanza rimanga sul riferimento), quindi in quel caso non può accedere alle variabili locali da quando sono sparite, a meno che non le contrassegnali come finale

7

È perché la classe interna all'interno di una funzione esegue effettivamente una copia della variabile locale perché la variabile locale può essere distrutta dopo la chiamata della funzione mentre l'istanza della classe locale esiste ancora. Per fare in modo che le due copie della variabile locale abbiano sempre lo stesso valore (per farle sembrare identiche), devi dichiarare la variabile come definitiva.

0

Secondo il modello di memoria Java, l'utilizzo della variabile finale garantisce che la variabile finale sia sempre inizializzata. Viene visualizzato un errore quando si tenta di utilizzare la variabile locale senza inizializzazione. usando la garanzia finale della classe interna che la variabile locale che è stata usata viene inizializzata.