Contents | Prev | Next | Inner Classes Specification

# How do inner classes affect the idea of `this` in Java code?

Recall that the code of a top-level class T can make use of the current instance, either directly by means of the keyword `this`, or indirectly, by naming one of the instance members of T. The idea of a current instance has been extended, so that inner classes have more than one current instance. This allows the code of an inner class C to execute relative to an enclosing instance of its outer class, as well as the current instance of C.

In our first example of adapter classes, the `Enumerator` code had two current instances, the enclosing `FixedStack` and the `Enumerator` object itself. More generally, within the entire body of an inner class C, there is a current instance for C, another current instance for every inner class enclosing C, and finally a current instance for the innermost enclosing top-level class. (A `static` class is a top-level class, not an inner class. Therefore, our enumeration of current instances stops at the first `static` keyword.)

Top-level classes do not have multiple current instances. Within the non- `static` code of a top-level class T, there is one current instance of type T. Within the `static` code of a top-level class T, there are no current instances. This has always been true of top-level classes which are package members, and is also true of top-level classes which are `static` members of other top-level classes. It is as if all package members have been implicitly `static` all along.

In all classes, each current instance can be named explicitly or can play an implicit part when its members are used. Any current instance can be referred to by explicitly qualifying the keyword `this` as if it were a name: `FixedStack.this`, `Enumerator.this`, etc. (This notation is always effective, since the language prohibits an inner class from having the same name as any of its enclosing classes.) As always, the innermost current instance can be named with the unqualified keyword `this`.

Remember that an instance variable reference m has the same meaning as a field reference expression `this.`m, so the current instance is implicitly used. In a given piece of code, all members of all current classes are in scope and usable (except for name hiding by intervening scopes). The simple name of a member is implicitly qualified by the current instance in whose class the name was found. (All `static` members of enclosing classes are always usable.)

In particular, Java code can directly use all methods of all current instances. Class scoping does not influence overloading: If the inner class has one `print` method, the simple method name `print` refers to that method, not any of the ten `print` methods in the enclosing class.

## Enclosing classes and instantiation

It is sometimes useful to speak of an enclosing instance of an inner class C. This is defined as any current instance within C, other than the instance of C itself. Every instance of C is permanently associated with its enclosing instances.

When a constructor is invoked, the new object must be supplied with an enclosing instance, which will become a current instance for all the code executed by the new object. (If there are layers of enclosing instances, the innermost is required, and it in turn determines all the others.) The enclosing instance may be specified explicitly, by qualifying the keyword `new`:

        class Automobile {
            class Wheel {
                String hubcapType;
                float radius;
            }

            Wheel leftWheel = this. new Wheel();
            Wheel rightWheel = this. new Wheel();
            Wheel extra;

            static void thirdWheel(Automobile car) {
                if (car.extra == null) {
                    car.extra = car. new Wheel();
                }
                return car.extra;
            }
        }

        class WireRimWheel extends Automobile.Wheel {
            WireRimWheel(Automobile car, float wireGauge) {
                car. super();
            }
        }

A subclass of an inner class C must pass an enclosing instance to C's constructor. This may be done, as just shown, by explicitly qualifying the keyword `super`. By default, a current instance of the caller becomes the enclosing instance of a new inner object. In an earlier example, the expression `new Enumerator()` is equivalent to the explicitly qualified `this.new Enumerator()`. This default is almost always correct, but some applications (such as source code generators) may need to override it from time to time.

Contents | Prev | Next

Inner Classes Specification (HTML generated by dkramer on March 15, 1997)
Copyright © 1996, 1997 Sun Microsystems, Inc. All rights reserved
Please send any comments or corrections to john.rose@eng.sun.com