Доступ к методу "this" из анонимного класса в Java
Быстрый ответ
Для доступа к экземпляру внешнего класса из анонимного класса используйте конструкцию OuterClassName.this
.
Посмотрим на пример:
public class Outer {
private int value = 123;
public void method() {
new Thread() {
public void run() {
System.out.println(Outer.this.value);
}
}.start();
}
}
new Outer().method(); // Отобразит: 123
В данном примере Outer.this.value
предоставляет доступ к переменной value
внешнего класса Outer
из анонимного класса.
Зачем и когда применять OuterClassName.this
OuterClassName.this
применяется для четкого обращения к элементам внешнего класса, позволяя тем самым избежать путаницы в областях видимости анонимных классов.
Прояснение областей видимости
Давайте рассмотрим разницу между локальными и внешними переменными на примере:
public class Device {
private String serialNumber = "123456";
public void initialize() {
Runnable runnable = new Runnable() {
public void run() {
String serialNumber = "654321";
System.out.println(serialNumber); // Выводит на экран локальный serialNumber: 654321
System.out.println(Device.this.serialNumber); // Выводит на экран serialNumber из внешнего класса Device: 123456
}
};
runnable.run();
}
}
В этом случае Device.this.serialNumber
помогает правильно определить область видимости и обратиться к переменной serialNumber
внешнего класса Device
.
Компромиссы альтернативных подходов
Теоретически можно было создать дополнительное поле или метод в классе Outer
, однако это потребовало бы дополнительное сопровождение кода и могло вызвать путаницу. Проще и надёжнее использовать стандартное обращение через Outer.this
.
Устранение неоднозначности
Для предотвращения ошибок, вызванных пересечением имён переменных, следует использовать OuterClassName.this
для четкого обращения к элементам внешнего класса.
Визуализация
На примере можно проиллюстрировать следующим образом:
Основной объект (📺): Это ваш телевизор.
Анонимный класс (🎮): Игровая консоль, подключенная к телевизору.
Ссылки на this
:
📺 Пульт (this): Управляет телевизором (Основной объект).
🎮 Кнопка на игровом контроллере (OuterClassName.this): Управляет телевизором через игровую консоль (Анонимный класс).
Заключение:
В контексте 🎮 `this` ссылается непосредственно на 🎮.
Для управления 📺, используйте `OuterClassName.this`.
Таким образом, OuterClassName.this
позволяет взаимодействовать с «телевизором» прямо с «игровой консоли».
Технические аспекты кода
Приведем пример использования в коде:
public class Car {
public void start() {
System.out.println("Car starting"); // Заводим автомобиль.
}
public void drive() {
new Object() {
void execute() {
Car.this.start(); // Запускаем автомобиль.
System.out.println("Enjoy the trip!"); // Начинаем движение.
}
}.execute();
}
}
Здесь Car.this.start()
обеспечивает вызов метода start
именно для объекта класса Car.
public class Garden {
void water() {
System.out.println("Watering the garden"); // Поливаем сад.
}
public void maintain() {
new Thread() {
public void run() {
water(); // Попытка полить сад.
}
void water() {
Garden.this.water(); // Обеспечиваем, что мы поливаем именно сад, а не что-то иное.
}
}.start();
}
}
Если методы с одинаковыми названиями присутствуют и в анонимном, и во внешнем классах, Garden.this.water()
помогает ясно указать, какой из методов следует вызвать.
Полезные материалы
- Вложенные классы в Java – разъяснение природы вложенных классов и их взаимосвязи с
this
. - Анонимные классы в Java – подробное описание работы с анонимными классами.
- Ссылка на this в Java – GeeksforGeeks – анализ различий в применении
this
в Java. - Как получить доступ к объекту внешнего класса из объекта внутреннего класса – обсуждение этой проблематики на Stack Overflow.
- Анонимные классы в Java – javatpoint – детальное разъяснение принципов работы анонимных классов на примерах.