Всегда ли анонимный внутренний класс захватывает ссылку на «этот» (внешний) объект при доступе к его примитивам и т. Д.? - PullRequest
7 голосов
/ 21 декабря 2011

Если у меня есть

[EDIT: добавлено определение типа для "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();
    }
}

вызовет inner.execute() установит переменную outerInt для этого конкретного Outer объекта на 5, откуда бы он ни вызывался, и до тех пор, пока этот Inner объект существует? Или это просто изменит копию переменной outerInt и не повлияет на исходный объект Outer?

Ответы [ 4 ]

6 голосов
/ 21 декабря 2011

Это будет захватывать и изменять внешние this.

См. spec

3 голосов
/ 21 декабря 2011

Чтобы ответить на ваш новый уточненный вопрос (из комментария к моему другому ответу):

Да .
Все внутренние и локальные классы будут иметь ссылку на this своих родителей, даже если они никогда не будут его использовать.
Демо .

0 голосов
/ 26 декабря 2011

Да, это так.Но если вам нужно использовать экземпляр внешнего класса, например, передать какой-то метод, вы должны сказать Outer.this.

0 голосов
/ 21 декабря 2011

Это не обязательно так.Вы не показали это объявление класса для Inner.Если Inner имеет поле с именем externalInt, то оно будет изменено.Иначе Outer'sInt будет.Если вы запустите:

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

    }
}

Вы получите 0, а не 5.

Но, комментируя externalInt во Inner, вы получите 5

...