When calling loadClass()
on a ClassLoader
, does the ClassLoader
first check if the class has been loaded, or does it immediately delegate this check to its parent ClassLoader
?
Java API says:
When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself.
But there's a specific chapter about class loader in the book Java Reflection in Action that says:
Class loader calls findLoadedClass to check if the class has been loaded already. If a class loader does not find a loaded class, calls loadClass on the parent class loader.
Which is correct?
A proper class loader implementation will:
The default implementation of ClassLoader.loadClass is something like:
protected synchronized Class<?> loadClass(String name, boolean resolve) {
// First, check if this class loader has directly defined the class or if the
// JVM has initiated the class load with this class loader.
Class<?> result = findLoadedClass(name);
if (result == null) {
try {
// Next, delegate to the parent.
result = getParent().loadClass(name);
} catch (ClassNotFoundException ex) {
// Finally, search locally if the parent could not find the class.
result = findClass(ex);
}
}
// As a remnant of J2SE 1.0.2, link the class if a subclass of the class
// loader class requested it (the JVM never calls the method,
// loadClass(String) passes false, and the protected access modifier prevents
// callers from passing true).
if (resolve) {
resolveClass(result);
}
return result;
}
Some class loader implementations will delegate to other non-parent class loaders (OSGi, for example, delegates to a graph of class loaders depending on the package), and some class loader implementations will look for classes in a local classpath before delegating.