2011-12-21 14 views
6

Se hoUna classe interna anonima acquisisce sempre un riferimento a "questo" oggetto (esterno) quando accede ai suoi primitivi ecc.?

[EDIT: aggiunta la definizione del tipo di "Inner"]

interface Inner{ 
    public void execute(); 
} 

class Outer{ 
    int outerInt; 
    public void hello(){ 
     Inner inner = new Inner(){ 
      public void execute(){ 
       outerInt=5; 
      } 
     } 

     //later 
     inner.execute(); 
    } 
} 

sarà la chiamata al inner.execute() impostare la outerInt variabile quel particolareOuter oggetto da 5, ovunque esso sia chiamato da, e per tutto il tempo che esiste l'oggetto Inner? O cambierà semplicemente una copia della variabile outerInt e non avrà effetto sull'oggetto originale Outer?

+0

Penso che tu intendessi "Esterno interno = nuovo Esterno()". – toto2

+0

@ toto2 No, non l'ha fatto. Sebbene 'Inner' non sia mostrato. – Bohemian

+0

@ toto2 Non credo che l'abbia fatto. – corsiKa

risposta

3

Per rispondere alla tua domanda di recente chiarito (dal commento la mia altra risposta):

.
Tutte le classi interne e locali avranno un riferimento allo this del genitore, anche se non lo usano mai.
Demo.

6

Questo acquisirà e modificherà l'esterno this.

Vedi l'spec

+1

_pun intended_ – SLaks

+0

Cioè, questo interno non è questo esterno. –

+0

@ toto2: No. Usando un campo della classe esterna si cattura _outer_ 'this'. – SLaks

0

Questo non è necessariamente vero. Non hai mostrato è la dichiarazione di classe per Inner. Se Inner ha un campo chiamato outerInt, allora quello sarà modificato. Altrimenti, l'esterno sarà esterno. Se si esegue:

public class Outer { 

    int outerInt = 0; 

    public void hello() { 
     Inner inner = new Inner() { 
      @Override 
      public void execute() { 
       outerInt = 5; 
      } 
     }; 

     // later 
     inner.execute(); 
     System.out.println(outerInt); 
    } 

    public static void main(String[] args) { 
     Outer o = new Outer(); 
     o.hello(); 
    } 
} 

class Inner { 
    int outerInt; 

    public void execute() { 

    } 
} 

Otterrete 0, non 5.

Ma commentando outerInt in interno, allora si ottiene 5

+0

Grazie. Ho modificato la domanda per mostrare che la data istanza 'Inner' non ha una variabile int chiamata' outerInt'. L'oggetto 'Interno' manterrà ancora un riferimento al' questo 'esterno, indipendentemente dal fatto che la variabile esterna sia riferita o meno? – Navigateur

+0

Quando si dice outerInt dall'interno della classe anonima, prima cerca un outerInt in quella classe e in ciascuna delle sue super classi. Quindi, se non viene trovato, ne verifica uno in Outer e quindi ognuna delle sue super classi e quindi se Outer è contenuto in una classe ne controlla uno e così via. Se non si trova nessuno, si dovrebbe ottenere un errore in fase di compilazione. Java non crea mai copie implicite di oggetti. – dspyz

+0

Oh, vedo cosa stai chiedendo ora. Sia per le classi interne anonime che per le classi interne regolari la risposta è la stessa. Se dichiari una classe in un'altra senza usare la parola chiave statica, puoi immaginare che l'istanza in cui la classe è dichiarata sia parte della definizione della classe. Se si nomina esplicitamente la propria classe interna (ad esempio, la classe MyInner estende Inner {...), non è possibile creare un'istanza con la nuova Outer.MyInner perché non sa a quale istanza associare MyInner con (Ci sarà un errore di compilazione a tale effetto). Puoi dire o = new Outer(). E poi o.nuovo MyInner(). – dspyz

0

Sì, sì. Ma se hai bisogno di usare l'istanza della classe esterna, ad es. passando ad un metodo, devi dire Outer.questo.