Contents | Prev | Next | Inner Classes Specification |
.
' replaced by `/
', followed (if the package
name is not null) by another `/
', and then by the simple name of T. The
bytecode name of T also serves as a prefix for the bytecode name of every class
defined within the body of T.
The bytecode name of a class C which is a non-private
member of another
class, and which is not contained (directly or indirectly) in any block or
private
class, is defined as the bytecode name of the immediately-enclosing
class, followed by `$
', followed by the simple name of C.
All other classes are called inaccessible. No inaccessible class N can ever be referenced by the code of any other compilation unit. Thus, as long as the name of N is chosen by the compiler in such as way as not to conflict with any other class in the same compilation unit, the name will be globally unique, because (as required previously) its prefix is unique to the package member in which it occurs.
For the sake of tools, there are some additional requirements on the naming of
an inaccessible class N. Its bytecode name must consist of the bytecode name
of an enclosing class (the immediately enclosing class, if it is a member),
followed either by `$
' and a positive decimal numeral chosen by the compiler,
or by `$
' and the simple name of N, or else by both (in that order). Moreover,
the bytecode name of a block-local N must consist of its enclosing package
member T, the characters `$1$
', and N, if the resulting name would be unique.
The string produced by the getName
method of Class
is derived, in all of
these cases, from the bytecode name, by replacing `/
' by `.
'. There is no
attempt to "clean up" the name to make it resemble Java source code.
InnerClasses
CONSTANT_Class
entries) to bytecode names of classes or interfaces which are not package
members. If so, the bytecodes must also contain an class attribute called
InnerClasses
which declares the encoding of those names. This attribute
contains an array of records, one for each encoded name:
Each array element records a class with an encoded name, its defining scope,
its simple name, and a bitmask of the originally declared, untransformed
access flags. If an inner class is not a member, its outer_class_info_index
is zero. If a class is anonymous, its inner_name_index
is zero.
If a class C was declared protected
, the public
access flag bit is cleared in
its InnerClasses
record, even though it is set in C's access_flags
field.
If the outer_class_info_index
of a record refers to a class E which itself is
not a package member, then an earlier record of the same InnerClasses
attribute must describe E.
If a class has members which are types, it must have an InnerClasses
attribute, with a record for each of the types. The rules already given imply
that a class which is not a package member has an InnerClasses
attribute
which has a record for it and all of its enclosing classes, except the outermost.
These rules ensure that compilers and debuggers can correctly interpret
bytecode names without parsing them, and without opening additional files to
examine inner class definitions. Compilers are allowed to omit
InnerClasses
records for inaccessible classes, but they are encouraged to
include records for all classes, especially when the code is being compiled for
use with a debugger.
Synthetic
private
unless noted otherwise, or they are at most of package scope.
Java 1.1 compilers are required, when producing bytecodes, to mark any field
or member not directly defined in the source code with an attribute named
Synthetic
. (At present, the length must be zero.) This will allow other
compilers to avoid inadvertant source-level references to non-private hidden
members, and will allow tools to avoid displaying them unnecessarily.
(A corresponding mechanism for declaring a local variable to be Synthetic
may also be introduced.)
Java 1.1 compilers are strongly encouraged, though not required, to use the following naming conventions when implementing inner classes. Compilers may not use synthetic names of the forms defined here for any other purposes.
A synthetic field pointing to the outermost enclosing instance is named
this$0
. The next-outermost enclosing instance is this$1
, and so forth. (At
most one such field is necessary in any given inner class.) A synthetic field
containing a copy of a constant v is named val$
v. These fields are final
.
All these synthetic fields are initialized by constructor parameters, which have the same names as the fields they initialize. If one of the parameters is the innermost enclosing instance, it is the first. All such constructor parameters are deemed to be synthetic. If the compiler determines that the synthetic field's value is used only in the code of the constructor, it may omit the field itself, and use only the parameter to implement variable references.
A non-private
final
synthetic method which grants access to a private
member or constructor has a name of the form access$
N, where N is a
decimal numeral. The organization of such access protocols is unspecified.
Debuggers and similar tools which are 1.1 compatible must recognize these naming conventions, and organize variable displays and symbol tables accordingly. Note that tools may need to parse these names. Compilers are strongly encouraged to use these conventions, at least by default.
Implementations of the Java Virtual Machine may verify and require that the synthetic members specified here are defined and used properly. It is reasonable to exploit the nature of synthetic members by basing optimization techniques on them.
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