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:

  1. How to create inner classes outside of the enclosing class scope.
  2. 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