12.2 Loading of Classes and Interfaces
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 §13.1. The method defineClass
(§20.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
(§20.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 (§12.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
(§20.14) and SecurityManager
(§20.17).
An entry may be deleted from the internal table only after unloading (§12.8) the class or interface represented by the class object in the entry.