Explain Codes LogoExplain Codes Logo

Access "this" from Java anonymous class

java
singleton
best-practices
object-oriented-programming
Nikita BarsukovbyNikita Barsukov·Jan 28, 2025
TLDR

Call the enclosing class from within an anonymous inner class using the outer class name prefixed to this – expressed as OuterClassName.this.

Example:

public class Outer { private int value = 123; public void method() { new Thread() { public void run() { // Peeking into the outer class 'value', like glancing at your neighbor's test System.out.println(Outer.this.value); } }.start(); } } // Bring the code to life new Outer().method(); // Prints: 123

In this code snippet, Outer.this.value fetches the value field from the Outer class when invoked within an anonymous inner class.

Why and when to use OuterClassName.this

Using this within an anonymous class context can sometimes mix up the scopes. Specifying OuterClassName.this is a practical way to reference fields or methods in the enclosing class.

Clarifying scopes

Consider this example:

public class Device { private String serialNumber = "123456"; public void initialize() { Runnable runnable = new Runnable() { public void run() { String serialNumber = "654321"; System.out.println(serialNumber); // Doppelgänger Alert! This prints the local serialNumber: 654321 System.out.println(Device.this.serialNumber); // This is the real McCoy, fetches the enclosing serialNumber: 123456 } }; runnable.run(); } }

In this example, using Device.this.serialNumber serves to distinguish the serialNumber of the Device instance from the serialNumber inside the anonymous inner class.

Trade-offs of alternative approaches

You could add a field to the Outer class in order to access its select method, a valid solution. However, it adds extra baggage: maintaining an additional field, plus a potential for duplicity and maintenance issues in evolving code. It's cleaner and more maintainable to directly reference methods or variables through the instance – Outer.this.select().

Avoiding ambiguity

Be wary of shadowing situations, where an inner class variable shares its name with one in the outer class. Always use OuterClassName.this for explicitly refering to the outer class’s fields or methods to avoid unintentional bugs.

Code nuts and bolts

Consider this scenario:

public class Car { public void start() { System.out.println("Car starting"); // *Vroom Vroom* Car's engine starts roaring! } public void drive() { new Object() { void execute() { Car.this.start(); // Initiates the Car's start method System.out.println("Enjoy the trip!"); // You're on the road, let's roll } }.execute(); } }

The Car.this.start() ensures we're calling the start method on the Car object, not mistakenly on the anonymous class object.

  • Indeed, naming conflicts are a problem, especially when the same methods exist in the anonymous and enclosing classes.
public class Garden { void water() { System.out.println("Watering garden"); // Garden is feeling thirsty } public void maintain() { new Thread() { public void run() { water(); // Attempting to quench the garden's thirst } void water() { Garden.this.water(); // Ensures the Garden's thirst is quenched, not the Thread's! } }.start(); } }

When two methods with the same name exist, one in the anonymous class and the other in the enclosing class, things can get hairy! By using Garden.this.water(), you unequivocally invoke the enclosing instance method.