Contents | Prev | Next | Inner Classes Specification |
The JavaSoft Java 1.1 compiler arranges this by adding an extra private
instance variable which links the inner class to the enclosing class. This variable is initialized from an extra argument passed to the inner class constructor. That argument, in turn, is determined by the expression which creates the inner class instance; by default it is the object doing the creation.
The Java 1.1 Language Specification specifies that the name of a type which is a class member, when transformed into Java 1.0 code for the purpose of generating Java virtual machine bytecodes, consists of the fully qualified name of the inner class, except that each `.
' character following a class name is replaced by a `$
'. In addition, each inner class constructor receives the enclosing instance in a prepended argument. Here is how the transformed source code of the FixedStack
example might look:
Anyone who has already programmed with Java or C++ adapter classes has written code similar to this, except that the link variables must be manually defined and explicitly initialized in top-level adapter classes, whereas the Java 1.1 compiler creates them automatically for inner classes.
When the Enumerator
needs to refer to the top
or array
fields of the enclosing instance, it indirects through a private
link called this$0
. The spelling of this name is a mandatory part of the transformation of inner classes to the Java 1.0 language, so that debuggers and similar tools can recognize such links easily. (Most programmers are happily unaware of such names.)
(Note: There is a limitation in some implementations of Java 1.1, under which the initialization of this$0
is delayed until after any superclass constructor is run. This means that up-level references made by a subclass method may fail if the method happens to be executed by the superclass constructor.)
In order to make a local variable visible to a method of the inner class, the compiler must copy the variable's value into a place where the inner class can access it. References to the same variable may use different code sequences in different places, as long as the same value is produced everywhere, so that the name consistently appears to refer to the same variable in all parts of its scope.
By convention, a local variable like array
is copied into a private
field val$array
of the inner class. (Because array
is final
, such copies never contain inconsistent values.) Each copied value is passed to the inner class constructor as a separate argument of the same name.
Here is what the resulting transformed code looks like:
A compiler may avoid allocating an inner class field to a variable, if it can determine that the variable is used only within the inner class constructors.
Notice that a class defined by a block, like E
, is not a member of its enclosing class, and so it cannot be named outside of its block. This is the same scoping restriction as applies to local variables, which also cannot be named outside of their blocks. In fact, any class contained in a block (whether directly or inside an intervening local class) cannot be named outside the block. All such classes are called inaccessible. For purposes of linking, the compiler must generate a unique externally visible name for every inaccessible class. The overall form of these names is a class name, followed by additional numbers or names, separated by $
characters.
Also, variable names synthesized by the compiler beginning with this$
and val$
must follow the usage patterns described here.
These names and conventions must be recognized by 1.1-compliant tools, and are strongly suggested for most compilation purposes. They are discussed further in the section on binary compatibility.
It must be emphasized that these oddly-named "this$
" and "val$
" fields and extra constructor arguments are added by the compiler to the generated bytecodes, and cannot be directly referenced by Java source code. Likewise, bytecode-level class names like MyOuterClass$19
cannot be used by source code (except under pre-1.1 compilers, which know nothing of inner classes).
Inner Classes Specification (HTML generated by dkramer on February 13, 1997)
Copyright © 1996, 1997 Sun Microsystems, Inc.
All rights reserved
Please send any comments or corrections to john.rose@eng.sun.com