Question

Consider the following classes:

public class A {
    public int a;

    public class B {
         public int b;

         public void foo() {
             System.out.println(A.this.a);
             System.out.println(this.b);
         }
    }
}

In foo, I access the outer A instance from within B using the syntax A.this. This works well because I'm trying to access the outer instance of A from the "current object" in B. However, what do I do if I want to access the outer A object from a variable of type B?

public class A {
    public int a;

    public class B {
         public int b;

         public void foo(B other) {
             System.out.println(other.A.this.a); // <-- This is (obviously) wrong. What SHOULD I do here?
             System.out.println(other.b);
         }
    }
}

What's the correct syntax to access the "outer" instance from the "inner" instance other in foo?

I realize I can access the outer variable a using simply other.a. Please forgive the contrived example! I just couldn't think of a better way to ask how to reach other.A.this.

Was it helpful?

Solution

As far as I can tell from the Java language specification, Java does not provide a syntax for such access. You can work around it by providing your own accessor method:

public class A {
    public int a;

    public class B {
         public int b;
         // Publish your own accessor
         A enclosing() {
             return A.this;
         }
         public void foo(B other) {
             System.out.println(other.enclosing().a);
             System.out.println(other.b);
         }
    }
}

OTHER TIPS

Well, you can't do that directly, as there is no such way defined in Java language. However, you can use some reflection hack to get the value of that field.

Basically, the inner classes store a reference to the enclosing class in the field named this$0. You can find more detail in this other post on SO.

Now, using reflection, you can access that field, and get the value of any attribute for that field:

class A {
    public int a;

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

    public class B {
         public int b;

         public B(int b) { this.b = b; }

         public void foo(B other) throws Exception {
             A otherA = (A) getClass().getDeclaredField("this$0").get(other); 
             System.out.println(otherA.a);
             System.out.println(other.b);
         }
    }
}

public static void main (String [] args) throws Exception {
    A.B obj1 = new A(1).new B(1);
    A.B obj2 = new A(2).new B(2);
    obj2.foo(obj1);
}

This will print 1, 1.

But as I said, this is just a hack. You wouldn't want to write such a code in real application. Rather you should go with a cleaner way as depicted in @dashblinkenlight's answer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top