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 March 15, 1997)
Copyright © 1996, 1997 Sun Microsystems, Inc.
All rights reserved
Please send any comments or corrections to john.rose@eng.sun.com