| CHAPTER 12: Execution |
Previous |
Java Language |
Index |
Next |
Linking 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.
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.
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.
Because linking involves the allocation of new data structures, it may fail with an OutOfMemoryError .
Verification ensures that the binary representation of a class or interface is structurally correct. For example, it checks that every instruction has a valid operation code; that every branch instruction branches to the start of some other instruction, rather than into the middle of an instruction; that every method is provided with a structurally correct signature; and that every instruction obeys the type discipline of the Java language.
For a more detailed description of the verification process, see the separate volume of this series, The Java Virtual Machine Specification.
If an error occurs during verification, then an instance of the following subclass of class LinkageError will be thrown at the point in the Java program that caused the class to be verified:
Preparation involves creating the static fields (class variables and constants) for a class or interface and initializing such fields to the standard default values (S4.5.4). This does not require the execution of any Java code; explicit initializers for static fields are executed as part of initialization (S12.4), not preparation.
Java implementations must detect the following error during preparation:
If such an error is detected, then an instance of AbstractMethodError should be thrown at the point in the Java program that caused the class to be prepared.
Implementations of the Java Virtual Machine may precompute additional data structures at preparation time in order to make later operations on a class or interface more efficient. One particularly useful data structure is a "method table" or other data structure that allows any method to be invoked on instances of a class without requiring a search of superclasses at invocation time.
A Java binary file references other classes and interfaces and their fields, methods, and constructors symbolically, using the fully-qualified names of the other classes and interfaces (S13.1). For fields and methods, these symbolic references include the name of the class or interface type that declares the field or method as well as the name of the field or method itself, together with appropriate type information.
Before a symbolic reference can be used it must be undergo resolution, wherein a symbolic reference is checked to be correct and, typically, replaced with a direct reference that can be more efficiently processed if the reference is used repeatedly.
If an error occurs during resolution, then an error will be thrown. Most typically, this will be an instance of one of the following subclasses of the class IncompatibleClassChangeError , but it may also be an instance of some other subclass of IncompatibleClassChangeError or even an instance of the class IncompatibleClassChangeError itself. This error may be thrown at any point in the program that uses a symbolic reference to the type, directly or indirectly:
Additionally, an UnsatisfiedLinkError (a subclass of LinkageError ) may be thrown if a class declares a native method for which no implementation can be found. The error will occur if the method is used, or earlier depending on what kind of resolution strategy is being used by the virtual machine (S12.3).
The symbolic references within a group of types may be resolved even before the group is loaded (S12.2.2), in an implementation that uses a special (non-standard) binary format (S13.1). This corresponds to the traditional practice of "linkage editing." Even if this is not done, a Java implementation has a lot of flexibility. It may resolve all symbolic references from a type at the point of the first linkage activity on the type, or defer the resolution of each symbolic reference to the first use of that reference.
We note that the flexibility accorded the Java implementation in the linkage process does not affect correctly formed Java programs, which should never encounter linkage errors.
| © 1996 Sun Microsystems, Inc. All rights reserved. |