Search code examples
javaclassloader

Java ClassLoader delegation model?


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?


Solution

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