HuntExams Academy logo
JavaAdvanced#jvm

What is the difference between a class loader's parent delegation model levels: Bootstrap, Extension/Platform, and Application?

Answer

Bootstrap ClassLoader loads core JDK classes (java.lang.*) from rt.jar/modules. Platform (formerly Extension) ClassLoader loads classes from the extensions directory. Application ClassLoader loads classes from the application's classpath. Each delegates loading requests to its parent first, ensuring core classes can't be overridden.

Example

System.out.println(String.class.getClassLoader()); // null (loaded by Bootstrap)
System.out.println(MyApp.class.getClassLoader()); // sun.misc.Launcher$AppClassLoader

Detailed explanation

Java’s built-in class loaders form a delegation hierarchy: Bootstrap → Extension/Platform → Application, from highest ancestor to lowest. Their main difference is which classes they are responsible for loading. Parent-first delegation lets a loader reuse classes supplied by its ancestors before searching its own sources. This supports consistent class identity and helps prevent application dependencies from replacing core Java types. In interviews, explain both this delegation flow and the changes introduced in Java 9.

The Bootstrap ClassLoader loads fundamental runtime classes, including java.lang.String and java.lang.Object. In typical Java 8 installations, these classes came from rt.jar; Java 9 and later use the modular runtime image instead. Bootstrap is implemented within the JVM rather than exposed as an ordinary ClassLoader object. Therefore, String.class.getClassLoader() returns null: null represents the bootstrap loader here, not an unloaded class or a missing loader. Bootstrap does not necessarily load every JDK class; other built-in loaders also define runtime classes.

In Java 8, the Extension ClassLoader loaded installed extensions from locations such as jre/lib/ext and directories configured through java.ext.dirs. Java 9 removed that extension mechanism and replaced this loader with the Platform ClassLoader. The platform loader loads selected Java platform modules and related runtime classes; it does not load an extensions directory. On Java 9+, ClassLoader.getPlatformClassLoader() provides access to it. The Application ClassLoader, also called the system loader in the standard configuration, normally loads application classes and libraries from the classpath and defines classes in many application modules resolved from the module path.

For the standard parent-first loadClass algorithm, a loader first checks whether the class is already loaded, delegates to its parent, and searches its own sources only if the parent cannot find it. Thus, an application request usually reaches Bootstrap before falling back through Platform and Application. Custom loaders can change this policy, subject to JVM constraints. MyApp.class.getClassLoader() normally identifies the application loader, but its concrete implementation name varies by JDK version and launch environment; sun.misc.Launcher$AppClassLoader is a Java 8-era name, not a portable expectation.

Key points to remember

  • Bootstrap loads fundamental runtime classes; its identity is represented by null in Class.getClassLoader().
  • Java 8’s Extension loader searched installed extension directories, including locations configured by java.ext.dirs.
  • Java 9+ uses the Platform loader for selected platform classes; the extension-directory mechanism was removed.
  • Application normally loads classpath dependencies and classes in many resolved application modules.
  • Standard loading checks already-loaded classes, delegates to the parent, and then tries local lookup.

Common mistakes candidates make

  • Claiming that the Java 9+ Platform ClassLoader still searches jre/lib/ext.
  • Treating rt.jar or sun.misc.Launcher$AppClassLoader as universal across JDK versions.
  • Saying every class loader must delegate parent-first or that Bootstrap loads all JDK classes.

Likely follow-up questions

Can a custom class loader use child-first loading?

Yes, a custom loader can implement local-first lookup, commonly for dependency isolation. However, JVM restrictions still apply: an ordinary custom loader cannot define classes in java.* packages.

Can two classes with the same fully qualified name be different types?

Yes: runtime class identity includes both the binary name and the defining class loader. If different loaders define the same name independently, those types are distinct, and casting between their instances can fail.

What is the difference between loadClass() and findClass()?

The standard loadClass() implementation coordinates the already-loaded check, parent delegation, and local lookup. findClass() performs the loader-specific search and definition, so custom loaders usually override it to preserve parent-first behaviour.

Interview tip: Draw the three-loader hierarchy, trace one parent-first request, and explicitly distinguish Java 8 extensions from Java 9+ platform modules.

Related Interview Questions

1
JavaAdvanced#jvm

What is JIT compilation?

Open
2
JavaIntermediate#oop#fundamentals

What is the difference between shallow copy and deep copy in Java?

Open
3
JavaAdvanced#oop#interface

What is the diamond problem and how does Java avoid it with interfaces?

Open