2

I'm trying to better understand the concept of anonymous classes in Java. From other answers on this website, I learned that an anonymous class can access non-final fields of the enclosing class using OuterClass.this.myField.

I made the following simple test case with an interface, AnonInt, and a class AnonTest with a method foo which returns an instance of an anonymous class implementing AnonInt. Dspite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?

public interface AnonInt {
    void print();
}

public class AnonTest {

    private int a;

    public AnonTest(int a) {
        this.a = a;
    }

    public AnonInt foo() {
        return new AnonInt() {

            public void print() {
                System.out.println(a);
            }
        };
    }

    public static void main(String[] args) {
        AnonTest at = new AnonTest(37);
        AnonInt ai = at.foo();
        ai.print();
    }
}

1 Answers1

6

Despite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?

Since the reference to a is unambiguous in your context, the two expressions reference the same field.

Generally, AnonTest.this is required in a very specific context - when your method needs to access AnonTest object itself, rather than accessing one of its members. In case of your program, this is unnecessary: the compiler resolves the expression a to the object AnonTest.this.a, and passes it to System.out.println.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thanks! Could you comment on Rich O'Kelly's answer in this thread: http://stackoverflow.com/questions/9545076/access-variables-of-outer-class-in-java? Would you need 'OuterClass.this.dialog' to access 'dialog'? Thanks! – Alexandre Vandermonde Sep 07 '16 at 16:53
  • 1
    @AlexandreVandermonde Since the old question is somewhat unclear as to what else is in the class where the `dialog` field is defined, the answer tries to be conservative, and cover a possibility of a naming conflict between `dialog` in `OuterClass.this` and some other `dialog` field or variable that may be in scope as well. When the situation is unambiguous, he could scrap his `dlg` variable, and use `dialog` in its place. – Sergey Kalinichenko Sep 07 '16 at 16:59