2011-12-21 10 views
6

Jeśli mamCzy anonimowa klasa wewnętrzna zawsze przechwytuje odwołanie do "tego" (zewnętrznego) obiektu podczas uzyskiwania dostępu do swoich prymitywów itp.?

[EDIT: dodano definicję typu dla "wewnętrzny"]

interface Inner{ 
    public void execute(); 
} 

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

     //later 
     inner.execute(); 
    } 
} 

będzie wywołanie inner.execute() ustawić outerInt zmienną że zwłaszczaOuter obiekt do 5, wszędzie tam, gdzie jest to wywoływana i tak długo, jak ten obiekt istnieje? A może po prostu zmieni kopię zmiennej outerInt i nie wpłynie na oryginalny obiekt Outer?

+0

Myślę, że chodziło o 'Zewnętrzny wewnętrzny = nowy zewnętrzny()'. – toto2

+0

@ toto2 Nie, nie zrobił tego. Chociaż 'Inner' nie jest wyświetlany. – Bohemian

+0

@ toto2 Nie sądzę, że tak. – corsiKa

Odpowiedz

3

Aby odpowiedzieć na nowo sprecyzować pytanie (z komentarzem do moja druga odpowiedź):

Tak.
Wszystkie wewnętrzne i lokalne klasy będą miały odniesienie do ich rodzica this, nawet jeśli nigdy z niego nie korzystają.
Demo.

6

Spowoduje to przechwycenie i zmodyfikowanie zewnętrznego this.

Zobacz spec

+1

_pun intention_ – SLaks

+0

To znaczy, że to nie jest zewnętrzne. –

+0

@ toto2: Nie. Użycie pola z klasy zewnętrznej powoduje przechwycenie _outer_ 'this'. – SLaks

0

To niekoniecznie jest prawdą. Nie pokazałeś to deklaracja klasy dla Innera. Jeśli Inner ma pole o nazwie outerInt, to zostanie zmodyfikowane. W przeciwnym razie zewnętrzna zewnętrzna będzie. Jeśli prowadzisz:

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() { 

    } 
} 

Dostaniesz 0, a nie 5.

ale zakomentowanie outerInt w Wewnętrzna, następnie dostać 5

+0

Dzięki. Edytowałem pytanie, aby pokazać, że dana instancja 'Inner' nie ma zmiennej typu int o nazwie' outerInt'. Czy obiekt "Wewnętrzny" nadal będzie odwoływał się do zewnętrznego "tego", niezależnie od tego, czy odnosi się do zmiennej zewnętrznej czy nie? – Navigateur

+0

Kiedy mówisz outerInt z wewnątrz anonimowej klasy, najpierw sprawdza zewnętrzną w klasie i każdej z jej super klas. Wtedy, jeśli nie zostanie znaleziony, sprawdza jeden w zewnętrznej, a następnie każdej z jego super klas, a następnie, jeśli zewnętrzna jest zawarta w klasie, sprawdza to i tak dalej. Jeśli nie zostanie znaleziony, powinieneś otrzymać błąd podczas kompilacji. Java nigdy nie tworzy niejawnych kopii obiektów. – dspyz

+0

Och, widzę, o co teraz pytasz. W przypadku anonimowych klas wewnętrznych lub zwykłych klas wewnętrznych odpowiedź jest taka sama. Jeśli zadeklarujesz jedną klasę w drugiej bez użycia słowa kluczowego static, możesz sobie wyobrazić, że instancja, w której deklarowana jest klasa, jest częścią definicji klasy. Jeśli jawnie nazwiesz swoją wewnętrzną klasę (np. Klasa MyInner rozszerza Wewnętrzną {...), nie możesz jej utworzyć za pomocą nowego Outer.MyInner, ponieważ nie wie, której instancji skojarzyć MyInnera z (wystąpi błąd kompilacji do tego efekt). Możesz powiedzieć o = new Outer(). A następnie o.new MyInner(). – dspyz

0

Tak jest. Ale jeśli masz potrzebę korzystania z instancji klasy zewnętrznej, np. przechodząc do jakiejś metody, musisz powiedzieć Outer.this.

Powiązane problemy