| CHAPTER 12: Execution |
Previous |
Java Language |
Index |
Next |
Loading 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 Class object to represent the class or interface.
The binary format of a class or interface is normally the class file format described in The Java Virtual Machine, but other formats are possible, provided they meet the requirements specified in S13.1. The method defineClass (S20.14.3) of class ClassLoader may be used to construct Class objects from binary representations in the class file format.
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 Class 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 loadClass (S20.14.2) 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.
The purpose of this internal table is to allow the verification process (S12.3.1) 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 ClassLoader (S20.14) and SecurityManager (S20.17).
An entry may be deleted from the internal table only after unloading (S12.8) the class or interface represented by the class object in the entry.
The loading process is implemented by the class ClassLoader (S20.14) and its subclasses. Different subclasses of ClassLoader 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.
If an error occurs during class loading, then an instance of one of the following subclasses of class LinkageError will be thrown at any point in the Java program that (directly or indirectly) uses the type:
Because loading involves the allocation of new data structures, it may fail with an OutOfMemoryError .
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.
| © 1996 Sun Microsystems, Inc. All rights reserved. |