Java Reference
In-Depth Information
How Nested Types Work
The preceding sections explained the features and behavior of the four kinds of nes‐
ted types. That should be all you need to know about nested types, especially if all
you want to do is use them. You may find it easier to understand nested types if you
understand how they are implemented, however.
The introduction of nested types did not change the Java Vir‐
tual Machine or the Java class file format. As far as the Java
interpreter is concerned, there is no such thing as a nested
type: all classes are normal top-level classes.
In order to make a nested type behave as if it is actually defined inside another class,
the Java compiler ends up inserting hidden fields, methods, and constructor argu‐
ments into the classes it generates. These hidden fields and methods are often
referred to as
synthetic
.
m
You may want to use the
javap
disassembler to disassemble some of the class files
for nested types so you can see what tricks the compiler has used to make the nested
types work. (See
Chapter 13
for information on
javap
.)
e
The implementation of nested types works by having
javac
compile each nested
type into a separate class file, which is actually a top-level class. The compiled class
files have a special naming convention, and have names that would not ordinarily
be created from user code.
Recall our first
LinkedStack
example (
Example 4-1
), which defined a static member
interface named
Linkable
. When you compile this
LinkedStack
class, the compiler
generates two class files. The first one is
LinkedStack.class
, as expected.
The second class file, however, is called
LinkedStack$Linkable.class
. The
$
in this
name is automatically inserted by
javac
. This second class file contains the imple‐
mentation of the static member interface defined in the exercise.
Because the nested type is compiled into an ordinary top-level class, there is no way
it can directly access the privileged members of its container. Therefore, if a static
member type uses a
private
(or other privileged) member of its containing type,
the compiler generates synthetic access methods (with the default package access)
and converts the expressions that access the
private
members into expressions that
invoke these specially generated methods.
The naming conventions for the four kinds of nested type are:
(Static or nonstatic) member types
Member types are named according to the
EnclosingType$Member.class
pattern.