Ensuring type safe linkage in the presence of class loaders requires special care. It is possible that when two different class loaders initiate loading of a class or interface denoted by N, the name N may denote a different class or interface in each loader. When a class or interface C = <N1, L1> makes a symbolic reference to a field or method of another class or interface D = <N2, L2>, the symbolic reference includes a descriptor specifying the type of the field, or the return and argument types of the method. It is essential that any type name N mentioned in the field or method descriptor denote the same class or interface when loaded by L1 and when loaded by L2. To ensure this, the Java Virtual Machine imposes loading constraints of the form NL1 = NL2 during preparation (§5.4.2) and resolution (§5.4.3). To enforce these constraints, the Java Virtual Machine will, at certain prescribed times (see §5.3.1, §5.3.2, §5.3.3, and §5.3.5), record that a particular loader is an initiating loader of a particular class. After recording that a loader is an initiating loader of a class, the Java Virtual Machine must immediately check to see if any loading constraints are violated. If so, the record is retracted, the Java Virtual Machine throws a LinkageError, and the loading operation that caused the recording to take place fails. Similarly, after imposing a loading constraint (see §5.4.2, §184.108.40.206, §220.127.116.11, and §18.104.22.168), the Java Virtual Machine must immediately check to see if any loading constraints are violated. If so, the newly imposed loading constraint is retracted, the Java Virtual Machine throws a LinkageError, and the operation that caused the constraint to be imposed (either resolution or preparation, as the case may be) fails. The situations described here are the only times at which the Java Virtual Machine checks whether any loading constraints have been violated. A loading constraint is violated if, and only if, all the following four conditions hold: There exists a loader L such that L has been recorded by the Java Virtual Machine as an initiating loader of a class C named N.
There exists a loader L' such that L' has been recorded by the Java Virtual Machine as an initiating loader of a class C ' named N.
The equivalence relation defined by the (transitive closure of the) set of imposed constraints implies NL = NL'.
C ≠ C '. A full discussion of class loaders and type safety is beyond the scope of this specification. For a more comprehensive discussion, readers are referred to Dynamic Class Loading in the Java Virtual Machine by Sheng Liang and Gilad Bracha (Proceedings of the 1998 ACM SIGPLAN Conference on Object-Oriented Programming Systems, Languages and Applications).