My question, in abstract terms, is:
How can a non-static inner class access the instance of the enclosing class? This is required for purposes of using the instance as a parameter in method calls and accessing methods and variables with identical names between the inner and enclosing class.
Like the keywords this
and super
allow you to access specific versions of methods and variables with identical names in the class and the parent, are there keywords to access versions of methods and variables in enclosing classes and enclosed classes?
If you are confused, continue reading:
Consider the following code example, with two classes and an inner class. Main and Outer are two classes in the package "myPackage" (on a side note, I could not get the following code to work without a package/in the default package, for unknown reasons). Inner is an inner, non-static class of Outer.
package myPackage;
public class Outer {
public void activate() {
System.out.println("Outer.activate");
}
public class Inner {
public void go() {
activate();
}
}
}
package myPackage;
import myPackage.Outer.Inner;
public class Main {
public static void main(String[] args) {
Outer myOuter = new Outer();
Inner myInner = myOuter.new Inner();
myInner.go();
}
}
Note that I construct an Inner
with myOuter.new Inner()
. Since Inner is non-static, it has to be constructed on top of an existing instance of its enclosing class: in this case, myOuter
. Therefore, when I call myInner.go()
, myInner
calls activate()
, which calls activate()
on its linked instance of the enclosing class. So myInner
calls myOuter.activate()
, and the output is:
Outer.activate
Now, consider the following changes:
package myPackage;
public class Outer {
public void activate() {
System.out.println("Outer.activate");
}
public class Inner {
public void activate() {
System.out.println("Inner.activate");
activate();
}
}
}
package myPackage;
import myPackage.Outer.Inner;
public class Main {
public static void main(String[] args) {
Outer myOuter = new Outer();
Inner myInner = myOuter.new Inner();
myInner.activate();
}
}
Now when I call myInner.activate()
, myInner
outputs, then calls activate()
. However, since Inner
now has a method called activate()
, myInner
uses that version instead of the version in the instance of the enclosing class. So myInner
calls myInner.activate()
, and the output is:
Inner.activate
Inner.activate
Inner.activate
Inner.activate
Inner.activate
Inner.activate
...
Over and over, and ends in a stack overflow error. So my question in this context is how to change Inner.activate()
such that it outputs, then calls its enclosing instance version's of activate()
instead of its own. The output would then be:
Inner.activate
Outer.activate
Thanks in advance for your assistance.
You access this
of the outer class by pre-pending the name of the class to this
keyword, as follows:
Outer.this.activate();
This resolves the scope of this
to reference the object of the outer class, which is implicitly stored inside objects of non-static inner classes.