2009-12-22 5 views
18

Nehmen Sie das folgende Beispiel:Wo sind die letzten lokalen Java-Variablen gespeichert?

public void init() { 
    final Environment env = new Environment(); 
    Runtime.getRuntime().addShutdownHook(new Thread() { 
     public void run() { 
      env.close(); 
     } 
    }); 
} 

Erstens wo env gespeichert? Ist es:

  • vom Compiler in eine versteckte Membervariable der inneren Klasse kopiert, die es
  • kopiert verweist, auf, und verwiesen auf, dem Heap
  • auf dem Stapel gelassen und irgendwie verwiesen dort
  • etwas anderes

Meine Vermutung ist die erste Option. Zweitens, machen Sie irgendwelche Leistungsprobleme, die daraus entstehen (anstatt einfach env als eine Mitgliedsvariable der Klasse zu erstellen und als solche zu referenzieren), besonders wenn Sie eine große Anzahl solcher innerer Klassenkonstrukte erstellen, die auf final local verweisen Variablen.

Antwort

18

Ja, sie werden kopiert, weshalb Sie die Variable als final deklarieren müssen. Auf diese Weise werden sie garantiert nicht geändert, nachdem die Kopie erstellt wurde.

Dies ist für Beispielfelder, die auch wenn nicht endgültig zugänglich sind, unterschiedlich. In diesem Fall erhält die innere Klasse einen Verweis auf die äußere Instanz, die sie für diesen Zweck verwendet.

private Environment env; // a field does not have to be final 

public void init() { 
    Runtime.getRuntime().addShutdownHook(new Thread() { 
     public void run() { 
      env.close(); 
     } 
    }); 
} 

Zweitens tun alle Performance-Probleme, die aus tun dies entstehen?

Im Vergleich zu was? Sie müssen das Feld oder die Variable für Ihre innere Klasse haben, um zu arbeiten, und eine Kopie ist ein sehr effizienter Weg. Es ist sowieso nur eine "seichte" Kopie: nur der Verweis auf die (in Ihrem Beispiel) Umgebung wird kopiert, nicht die Umgebung selbst.

+0

Also kann ich davon ausgehen, dass es keine Leistungsprobleme gibt, die daraus entstehen? – Joel

+0

Meine persönliche Liebling in diesem Bereich ist, dass die Verweise auf die äußere Instanz (für den Zugriff auf Felder, nicht Variablen, die kopiert werden) ein Problem sein können, wenn sie nicht benötigt werden: http://stackoverflow.com/questions/ 758570/is-it-possible-make-anonymous-inner-classes-in-java-static – Thilo

+0

verglichen mit der Referenzierung als Membervariable. Wenn es kopiert wird, dann meine Annahme ist, dass es keine Auswirkungen auf die Leistung gibt. – Joel