Java ClassLoader delegation model?

The two statements are not exactly mutually exclusive. The Class will only exist in the current ClassLoader's set of loaded classes if the parent ClassLoader had previously failed to find the Class. So,

When requested to find (the external data that describes) a class or resource, a ClassLoader instance will delegate the search for (the external data that describes) the class or resource to its parent class loader before attempting to find (the external data that describes) the class or resource itself.

Which does not prevent it from short-circuiting if it knows its parent can't find the class but it can (as shown by it previously loading the class)


The Java API is correct.

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.

From the Java Classloading Mechanism -

When loading a class, a class loader first "delegates" the search for the class to its parent class loader before attempting to find the class itself.


A proper class loader implementation will:

  1. Check if the class has already been loaded.
  2. Typically ask the parent class loader to load the class
  3. Attempt to find the class in its own class path.

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 delegation 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.