Preparation and Resolution
After successful verification, the class is prepared for use. Memory is allocated and
static variables in the class are readied for initialization.
At this stage, variables aren't initialized, and no bytecode from the new class has
been executed. Before we run any code, the JVM checks that every type referred to
by the new class file is known to the runtime. If the types aren't known, they may
also need to be loaded—which can kick off the classloading process again, as the
JVM loads the new types.
This process of loading and discovery can execute iteratively until a stable set of
types is reached. This is called the “transitive closure” of the original type that was
R e l e c t i o n
Let's look at a quick example, by examining the dependencies of java.lang.Object .
Figure 11-1 shows a simplified dependency graph for Object . It only shows the
direct dependencies of Object that are visible in the public API of Object , and the
direct, API-visible dependencies of those dependencies. In addition, the dependen‐
cies of Class on the reflection subsystem, and of PrintStream and PrintWriter on
the I/O subsystems, are shown in very simplified form.
In Figure 11.1 we can see part of the transitive closure of Object .
Once resolved, the JVM can finally initialize the class. Static variables can be initial‐
ized and static initialization blocks are run.
This is the first time that the JVM is executing bytecode from the newly loaded
class. When the static blocks complete, the class is fully loaded and ready to go.
Secure Programming and Classloading
Java programs can dynamically load Java classes from a variety of sources, including
untrusted sources, such as websites reached across an insecure network. The ability
to create and work with such dynamic sources of code is one of the great strengths
and features of Java. To make it work successfully, however, Java puts great emphasis
on a security architecture that allows untrusted code to run safely, without fear of
damage to the host system.
Java's classloading subsystem is where a lot of safety features are implemented. The
central idea of the security aspects of the classloading architecture is that there is
only one way to get new executable code into the process: a class.
1 As in Chapter 6 , we're borrowing the expression transitive closure from the branch of mathemat‐
ics called graph theory.