Анонимный класс Java и доступная частная переменная

#java #private #inner-classes

#java #Частное #внутренние классы

Вопрос:

 interface Test {
public void test();
}

public class TestMain {
private String h = "AAA";

public static void main(String[] args) {
    TestMain t = new TestMain();
}

public TestMain() {
    Test t = new Test() {
        public void test()  {
            System.out.println( h );
        }
    };

    t.test();
}

}
 

Приведенный выше источник работает хорошо.

Но я думаю, что переменная ‘h’ должна быть недоступна из анонимного класса. Мне нужно знать, почему это хорошо работает.

Заранее благодарим вас за всю вашу помощь!

Ответ №1:

Каждый экземпляр нестатического внутреннего класса имеет заключенный экземпляр — экземпляр внешнего класса, который он связал с ним через ссылочную переменную, хранящуюся во внутреннем объекте класса. Все члены включающего экземпляра доступны для объекта внутреннего класса через эту ссылку.

Конечно, компилятор заботится о добавлении этой ссылочной переменной, а также некоторых специальных функций доступа, которые объект внутреннего класса может использовать для доступа к закрытым членам объекта внешнего класса. Вы можете увидеть эти функции доступа, разобрав внешний класс с помощью javap -c .

Ответ №2:

Основное правило для определения доступности для частных членов, согласно разделу 6.6.1 спецификации языка Java:

[I] если член или конструктор объявлен закрытым, то доступ разрешен тогда и только тогда, когда он происходит в теле класса верхнего уровня, который содержит объявление члена или конструктора.

Ответ №3:

Вложенный класс является членом своего окружающего класса. Нестатические вложенные классы (внутренние классы) имеют доступ к другим членам окружающего класса, даже если они объявлены частными. Статические вложенные классы не имеют доступа к другим членам окружающего класса.

Комментарии:

1. Статические вложенные классы имеют доступ к частным статическим членам заключающего класса.

2. Да, это правильно, я имел в виду «не иметь доступа к нестатическим членам окружающего класса».

3. @SandeepRajeev : все еще не правильно. Учитывая экземпляр включающего класса — то есть, если он получает его в качестве аргумента метода или создает один из своих собственных — статический вложенный класс может получить доступ к закрытым членам этого экземпляра.

4. Итак, я имел в виду, что он не может получить прямой доступ, но, как вы сказали, он может получить доступ через ссылку на объект. Спасибо.