What is class loading, and what are the roles of the Bootstrap, Platform, and Application class loaders?

10 minadvancedclassloaderjvmclass-loading

Quick Answer

Class loading is the JVM's process of finding, reading, and linking .class files into runtime Class objects, done lazily and delegated up a loader hierarchy. The Bootstrap loader (native code) loads core java.* classes; the Platform loader loads JDK extension classes; the Application (system) loader loads your application's classpath/module-path classes, using parent-delegation so requests are checked upward first.

Detailed Answer

Class loading is how the JVM turns a .class file into a Class object usable at runtime. It happens lazily, on first active use of a class, and goes through three phases: loading (reading bytecode into memory), linking (verification, preparation of static fields, resolution of symbolic references), and initialization (running static initializers).

Class loaders form a hierarchy, and (by default) use parent delegation: before a loader tries to load a class itself, it asks its parent to try first. This prevents core classes from being shadowed by application code and lets each class have one authoritative loader.

  • Bootstrap class loader: written in native code (part of the JVM itself), loads the core Java SE classes (java.lang.*, java.util.*, ...) from the runtime's module image. Has no parent (represented as null in code).
  • Platform class loader (formerly "Extension" loader pre-Java 9): loads classes from platform/extension modules that aren't core but ship with the JDK.
  • Application (System) class loader: loads classes from your application's classpath or module path — this is the loader that finds your own compiled classes and third-party JARs, and is what ClassLoader.getSystemClassLoader() returns.

Frameworks (application servers, plugin systems) often add custom class loaders to isolate or hot-swap code, breaking strict delegation intentionally (e.g., to let a web app override a JDK-shipped library version) — this is also the mechanism behind subtle ClassNotFoundException/ClassCastException bugs when the same class gets loaded by two different loaders.