📄 12.doc.html
字号:
<html>
<head>
<title>The Java Language Specification Execution</title>
</head>
<body BGCOLOR=#eeeeff text=#000000 LINK=#0000ff VLINK=#000077 ALINK=#ff0000>
<a href="index.html">Contents</a> | <a href="11.doc.html">Prev</a> | <a href="13.doc.html">Next</a> | <a href="j.index.doc1.html">Index</a>
<hr><br>
<a name="44410"></a>
<p><strong>
CHAPTER 12 </strong></p>
<a name="44411"></a>
<h1>Execution</h1>
<hr><p>
<a name="44413"></a>
This chapter specifies activities that occur during execution of a Java program.
It is organized around the life cycle of a Java Virtual Machine and of the classes,
interfaces, and objects that form a Java program.
<p><a name="46419"></a>
A Java Virtual Machine starts up by loading a specified class and then invoking the method <code>main</code> in this specified class. Section <a href="12.doc.html#44444">§12.1</a> outlines the loading, linking, and initialization steps involved in executing <code>main</code>, as an introduction to the concepts in this chapter. Further sections specify the details of loading <a href="12.doc.html#44459">(§12.2)</a>, linking <a href="12.doc.html#44487">(§12.3)</a>, and initialization <a href="12.doc.html#44557">(§12.4)</a>.<p>
<a name="46572"></a>
The chapter continues with a specification of the procedures for creation of new class instances <a href="12.doc.html#44670">(§12.5)</a>; finalization of class instances <a href="12.doc.html#44748">(§12.6)</a>; and finalization of classes <a href="12.doc.html#48744">(§12.7)</a>. It concludes by describing the unloading of classes <a href="12.doc.html#44850">(§12.8)</a> and the procedure followed when a virtual machine exits <a href="12.doc.html#44857">(§12.9)</a>.<p>
<a name="44444"></a>
<h2>12.1 Virtual Machine Start-Up</h2>
<a name="44445"></a>
A Java Virtual Machine starts execution by invoking the method <code>main</code> of some
specified class, passing it a single argument, which is an array of strings. In the
examples in this specification, this first class is typically called <code>Test</code>.
<p><a name="46661"></a>
The manner in which the initial class is specified to the Java Virtual Machine is beyond the scope of this specification, but it is typical, in host environments that use command lines, for the fully-qualified name of the class to be specified as a command-line argument and for following command-line arguments to be used as strings to be provided as the argument to the method <code>main</code>. For example, in a UNIX implementation, the command line:<p>
<pre><a name="46662"></a>java Test reboot Bob Dot Enzo
</pre><a name="46663"></a>
will typically start a Java Virtual Machine by invoking method <code>main</code> of class <code>Test</code>
(a class in an unnamed package), passing it an array containing the four strings
<code>"reboot"</code>, <code>"Bob"</code>, <code>"Dot"</code>, and <code>"Enzo"</code>.
<p><a name="46666"></a>
We now outline the steps the virtual machine may take to execute <code>Test</code>, as an example of the loading, linking, and initialization processes that are described further in later sections.<p>
<a name="46619"></a>
<h3>12.1.1 Load the Class <code>Test</code></h3>
<a name="46533"></a>
The initial attempt to execute the method <code>main</code> of class <code>Test</code> discovers that the
class <code>Test</code> is not loaded-that is, that the virtual machine does not currently contain
a binary representation for this class. The virtual machine then uses a class
loader <a href="javalang.doc13.html#14462">(§20.14)</a> to attempt to find such a binary representation. If this process
fails, then an error is thrown. This loading process is described further in <a href="12.doc.html#44459">§12.2</a>.
<p><a name="46620"></a>
<h3>12.1.2 Link <code>Test</code>: Verify, Prepare, (Optionally) Resolve</h3>
<a name="47121"></a>
After <code>Test</code> is loaded, it must be initialized before <code>main</code> can be invoked. And <code>Test</code>,
like all (class or interface) types, must be linked before it is initialized. Linking
involves verification, preparation and (optionally) resolution. Linking is described
further in <a href="12.doc.html#44487">§12.3</a>.
<p><a name="47125"></a>
Verification checks that the loaded representation of <code>Test</code> is well-formed, with a proper symbol table. Verification also checks that the code that implements <code>Test</code> obeys the semantic requirements of Java and the Java Virtual Machine. If a problem is detected during verification, then an error is thrown. Verification is described further in <a href="12.doc.html#44491">§12.3.1</a>.<p>
<a name="48984"></a>
Preparation involves allocation of static storage and any data structures that are used internally by the virtual machine, such as method tables. If a problem is detected during preparation, then an error is thrown. Preparation is described further in <a href="12.doc.html#47979">§12.3.2</a>.<p>
<a name="46935"></a>
Resolution is the process of checking symbolic references from <code>Test</code> to other classes and interfaces, by loading the other classes and interfaces that are mentioned and checking that the references are correct.<p>
<a name="48724"></a>
The resolution step is optional at the time of initial linkage. An implementation may resolve symbolic references from a class or interface that is being linked very early, even to the point of resolving all symbolic references from the classes and interfaces that are further referenced, recursively. (This resolution may result in errors from these further loading and linking steps.) This implementation choice represents one extreme and is similar to the kind of "static" linkage that has been done for many years in simple implementations of the C language. (In these implementations, a compiled program is typically represented as an "<code>a.out</code>" file that contains  a fully-linked version of the program, including completely resolved links to library routines used by the program. Copies of these library routines are included in the "<code>a.out</code>" file.)<p>
<a name="46603"></a>
An implementation may instead choose to resolve a symbolic reference only when it is actively used; consistent use of this strategy for all symbolic references would represent the "laziest" form of resolution. In this case, if <code>Test</code> had several symbolic references to another class, then the references might be resolved one at a time, as they are used, or perhaps not at all, if these references were never used during execution of the program.<p>
<a name="46604"></a>
The only requirement on when resolution is performed is that any errors detected during resolution must be thrown at a point in the program where some action is taken by the program that might, directly or indirectly, require linkage to the class or interface involved in the error. Using the "static" example implementation choice described above, loading and linkage errors could occur before the program is executed if they involved a class or interface mentioned in the class <code>Test</code> or any of the further, recursively referenced, classes and interfaces. In a system  that implemented the "laziest" resolution, these errors would be thrown only when an incorrect symbolic reference is actively used.<p>
<a name="46607"></a>
The resolution process is described further in <a href="12.doc.html#44524">§12.3.3</a>.<p>
<a name="46634"></a>
<h3>12.1.3 Initialize <code>Test</code>: Execute Initializers</h3>
<a name="46618"></a>
In our continuing example, the virtual machine is still trying to execute the
method <code>main</code> of class <code>Test</code>. This is an attempted active use <a href="12.doc.html#44560">(§12.4.1)</a> of the class,
which is permitted only if the class has been initialized.
<p><a name="46639"></a>
Initialization consists of execution of any class variable initializers and static initializers of the class <code>Test</code>, in textual order. But before <code>Test</code> can be initialized, its direct superclass must be initialized, as well as the direct superclass of its direct superclass, and so on, recursively. In the simplest case, <code>Test</code> has <code>Object</code> as its implicit direct superclass; if class <code>Object</code> has not yet been initialized, then it must be initialized before <code>Test</code> is initialized. Class <code>Object</code> has no superclass, so the recursion terminates here.<p>
<a name="47019"></a>
If class <code>Test</code> has another class <code>Super</code> as its superclass, then <code>Super</code> must be initialized before <code>Test</code>. This requires loading, verifying, and preparing <code>Super</code> if this has not already been done and, depending on the implementation, may also involve resolving the symbolic references from <code>Super</code> and so on, recursively.<p>
<a name="47072"></a>
Initialization may thus cause loading, linking, and initialization errors, including such errors involving other types.<p>
<a name="47023"></a>
The initialization process is described further in <a href="12.doc.html#44557">§12.4</a>.<p>
<a name="47024"></a>
<h3>12.1.4 Invoke <code>Test.main</code></h3>
<a name="46653"></a>
Finally, after completion of the initialization for class <code>Test</code> (during which other
consequential loading, linking, and initializing may have occurred), the method
<code>main</code> of <code>Test</code> is invoked.
<p><a name="46532"></a>
The method <code>main</code> must be declared <code>public</code>, <code>static</code>, and <code>void</code>. It must accept a single argument that is an array of strings.<p>
<a name="44459"></a>
<h2>12.2 Loading of Classes and Interfaces</h2>
<a name="44460"></a>
<i>Loading</i> refers to the process of finding the binary form of a class or interface type
with a particular name, perhaps by computing it on the fly, but more typically by
retrieving a binary representation previously computed from source code by a
compiler, and constructing, from that binary form, a <code>Class</code> object to represent the
class or interface.
<p><a name="48259"></a>
The binary format of a class or interface is normally the <code>class</code> file format described in <i>The Java Virtual Machine</i>, but other formats are possible, provided they meet the requirements specified in <a href="13.doc.html#44909">§13.1</a>. The method <code>defineClass</code> <a href="javalang.doc13.html#52452">(§20.14.3)</a> of class <code>ClassLoader</code> may be used to construct <code>Class</code> objects from binary representations in the <code>class</code> file format.<p>
<a name="48266"></a>
A Java Virtual Machine system should maintain an internal table of classes and interfaces that have been loaded for the sake of resolving symbolic references. Each entry in the table should consist of a fully qualified class name (as a string), a class loader, and a <code>Class</code> object. Whenever a symbolic reference to a class or interface is to be resolved, a class loader is identified that is responsible for loading the class or interface, if necessary. The table should be consulted first, however; if it already contains an entry for that class name and class loader, then the class object in that entry should be used and no method of the class loader should be invoked. If the table contains no such entry, then the method <code>loadClass</code> <a href="javalang.doc13.html#14061">(§20.14.2)</a> of the class loader should be invoked, giving it the name of the class or interface. If and when it returns, the class object that it returns should be used to make a new entry in the table for that class name and class loader.<p>
<a name="47927"></a>
The purpose of this internal table is to allow the verification process <a href="12.doc.html#44491">(§12.3.1)</a> to assume, for its purposes, that two classes or interfaces are the same if they have the same name and the same class loader. This property allows a class to be verified without loading all the classes and interfaces that it uses, whether actively or passively. Well-behaved class loaders do maintain this property: given the same name twice, a good class loader should return the same class object each time. But without the internal table, a malicious class loader could violate this property and undermine the security of the Java type system. A basic principle of the design of the Java language is that the type system cannot be subverted by code written in Java, not even by implementations of such otherwise sensitive system classes as <code>ClassLoader</code> <a href="javalang.doc13.html#14462">(§20.14)</a> and <code>SecurityManager</code> <a href="javalang.doc16.html#46274">(§20.17)</a>.<p>
<a name="47984"></a>
An entry may be deleted from the internal table only after unloading <a href="12.doc.html#44850">(§12.8)</a> the class or interface represented by the class object in the entry.<p>
<a name="47907"></a>
<h3>12.2.1 The Loading Process</h3>
<a name="44471"></a>
The loading process is implemented by the class <code>ClassLoader</code> <a href="javalang.doc13.html#14462">(§20.14)</a> and its
subclasses. Different subclasses of <code>ClassLoader</code> may implement different loading
policies. In particular, a class loader may cache binary representations of
classes and interfaces, prefetch them based on expected usage, or load a group of
related classes together. These activities may not be completely transparent to a
running Java application if, for example, a newly compiled version of a class is
not found because an older version is cached by a class loader. It is the responsibility
of a class loader, however, to reflect loading errors only at points in the program
they could have arisen without prefetching or group loading.
<p><a name="44476"></a>
If an error occurs during class loading, then an instance of one of the following subclasses of class <code>LinkageError</code> will be thrown at any point in the Java program that (directly or indirectly) uses the type:<p>
<ul><a name="44477"></a>
<li><code>ClassCircularityError</code>: A class or interface could not be loaded because it would be its own superclass or superinterface <a href="13.doc.html#44994">(§13.4.4)</a>.
<a name="44481"></a>
<li><code>ClassFormatError</code>: The binary data that purports to specify a requested compiled class or interface is malformed.
<a name="44482"></a>
<li><code>NoClassDefFoundError</code>: No definition for a requested class or interface could be found by the relevant class loader.
</ul><a name="46207"></a>
Because loading involves the allocation of new data structures, it may fail with an <code>OutOfMemoryError</code>.<p>
<a name="44484"></a>
<h3>12.2.2 Loading: Implications for Code Generation</h3>
<a name="44485"></a>
A cooperating class loader can enable a code generator to generate code for a
group of class and interface types-perhaps an entire package-by loading the
binary code for these types as a group. A format can be designed that allows all
the internal symbolic references in such a group to be resolved, before the group is
loaded. Such a strategy may also allow the generated code to be optimized before
loading based on the known concrete types in the group. This approach may be
useful in specific cases, but is discouraged as a general technique, since such a
class file format is unlikely to be widely understood.
<p><a name="44487"></a>
<h2>12.3 Linking of Classes and Interfaces</h2>
<a name="44488"></a>
<i>Linking</i> is the process of taking a binary form of a class or interface type and combining
it into the runtime state of the Java Virtual Machine, so that it can be executed.
A class or interface type is always loaded before it is linked. Three different
activities are involved in linking: verification, preparation, and resolution of symbolic
references.
<p><a name="46466"></a>
Java allows an implementation flexibility as to when linking activities (and, because of recursion, loading) take place, provided that the semantics of the language are respected, that a class or interface is completely verified and prepared before it is initialized, and that errors detected during linkage are thrown at a point in the program where some action is taken by the program that might require linkage to the class or interface involved in the error.<p>
<a name="46467"></a>
For example, an implementation may choose to resolve each symbolic reference in a class or interface individually, only when it is used (lazy or late resolution), or to resolve them all at once while the class is being verified (static resolution). This means that the resolution process may continue, in some implementations, after a class or interface has been initialized.<p>
<a name="46201"></a>
Because linking involves the allocation of new data structures, it may fail with an <code>OutOfMemoryError</code>.<p>
<a name="44491"></a>
<h3>12.3.1 Verification of the Binary Representation</h3>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -