Using Inner Classes
(a very short tutorial)
Introduction
I always forget how to do two things with inner classes and I
always have trouble finding the information on the web. If you are
reading this you probably have the same problem.
This tutorial covers two aspects of inner classes:
- How to create inner classes outside of the enclosing class
scope.
- How to access shadowed members of the enclosing class.
Issue 1: Creating Instances
Non-static inner classes have a hidden reference to the enclosing
class instance. This means you must have an instance of the
enclosing class to create the inner class. You also have to use a
special "new" function that correctly initializes the hidden
reference to the enclosing class. The special "new" function is a
member of the enclosing class. I haven't seen syntax like this
anywhere else in the Java Pgramming Language, which is probably why
I find it so hard to remember.
InnerClassTest o = new InnerClassTest();
InnerClassTest.ReallyInner i = o.new ReallyInner();
Issue 2: Accessing Shadowed Members
If an enclosing class has a non-static function "foo()", a
non-static inner class can access that method by calling
"this.foo()" or just "foo()". What if the inner class also has a
method "foo()"? How can it access the "foo()" in the enclosing
class? It has to access that hidden reference. Again, this syntax
looks strange to me. It looks like you are accessing a static
member of the enclosing class.
InnerClassTest.this.foo();
There used to be a different way to access the enclosing class. You
used "this$0" or "this$1", where the trailing number indicated how
many levels up the enclosing hierarchy you wanted to access.
Someone decided that the '$' made tokenization of the language more
difficult and changed the spec.
Conclusion
That's it. A complete listing of source code demonstrating this
follows and is linked below.
InnerClassTest.java
public class InnerClassTest {
public void foo() {
System.out.println("Outer class");
}
public class ReallyInner {
public void foo() {
System.out.println("Inner class");
}
public void test() {
this.foo();
InnerClassTest.this.foo();
}
}
public static void main(String[] args) {
InnerClassTest o = new InnerClassTest();
InnerClassTest.ReallyInner i = o.new ReallyInner();
i.test();
}
}
Back
Copyright 2003 Alan Oursland