Back to Class Loading & Compilation
Q1Question 1 of 4

What is a class loader and what are the types?

Key Concepts
  • A class loader reads .class files and loads them into JVM memory
  • Bootstrap ClassLoader: loads core Java classes (java.lang, java.util) from rt.jar/modules
  • Platform ClassLoader (Extension): loads standard extensions (java.sql, javax packages)
  • Application ClassLoader: loads your application classes from the classpath
  • Custom class loaders: used by app servers, OSGi, and hot-deployment tools
  • Classes are loaded lazily – only when first referenced

Definition

A class loader reads .class bytecode from disk and loads it into JVM memory. Three built-in loaders form a delegation chain: Bootstrap → Platform → Application.

Three built-in class loaders:

  • Bootstrap ClassLoader: Loads core JDK classes (java.lang.String, java.util.HashMap). Written in native code.
  • Platform ClassLoader (was Extension): Loads standard library extensions.
  • Application ClassLoader: Loads your application classes from the classpath (-cp or -classpath).

Loading bank procedures: the head office library (Bootstrap) provides core rules. The regional library (Platform) provides specialized procedures. The branch shelf (Application) holds your specific application code.

Understanding the Concepts

The three class loaders

JAVA
// Check which class loader loaded each class
System.out.println(String.class.getClassLoader());           // null (Bootstrap)
System.out.println(java.sql.Connection.class.getClassLoader()); // PlatformClassLoader
System.out.println(Account.class.getClassLoader());          // AppClassLoader

Bootstrap returns null because it is implemented in native code, not as a Java object.

When are classes loaded?

Classes are loaded lazily – only when first referenced:

JAVA
public class Main {
    public static void main(String[] args) {
        System.out.println("Main loaded");
        // Account is NOT loaded yet

        Account a = new Account();  // NOW Account is loaded
    }
}

What happens during loading?

  1. Loading: Read .class bytes from disk/network/jar.
  2. Linking: Verify bytecode safety, prepare static fields (default values), resolve symbolic references.
  3. Initialization: Run static initializer blocks and static field assignments.

What should a senior engineer know?

  • App servers (Tomcat, WildFly) use per-webapp class loaders for isolation.
  • Spring Boot uber-jar uses a custom class loader to load classes from nested jars.
  • Hot reloading tools (JRebel, Spring DevTools) use custom class loaders to reload changed classes without restarting.
  • ClassNotFoundException means the class loader cannot find the .class file on the classpath. NoClassDefFoundError means it was found once but failed to load (e.g., static initializer exception).

What are common mistakes?

A common mistake is not understanding the concept fully before using it in production banking applications.

Wrong approach:

JAVA
package com.bank.service;

public class TransferService {
    public void transfer(String fromAccount, String toAccount, double amount) {
        // WRONG: using double for money
        double balance = getBalance(fromAccount);
        balance = balance - amount;
    }
    private double getBalance(String id) { return 10000.0; }
}

Correct approach:

JAVA
package com.bank.service;

import java.math.BigDecimal;

public class TransferService {
    public void transfer(String fromAccount, String toAccount, BigDecimal amount) {
        // CORRECT: using BigDecimal for money
        BigDecimal balance = getBalance(fromAccount);
        balance = balance.subtract(amount);
    }
    private BigDecimal getBalance(String id) { return new BigDecimal("10000.00"); }
}

Always use BigDecimal for monetary calculations in banking systems to avoid floating-point precision errors.

What are the edge cases?

Edge cases can cause unexpected behavior in banking applications. Here are some to watch for.

JAVA
package com.bank.edge;

public class EdgeCaseDemo {
    public static void main(String[] args) {
        // Edge case 1: null handling
        String accountId = null;
        try {
            System.out.println(accountId.length());
        } catch (NullPointerException e) {
            System.out.println("Null account ID");
        }

        // Edge case 2: empty vs null
        String emptyId = "";
        System.out.println(emptyId.isEmpty());  // true
        System.out.println(emptyId == null);     // false

        // Edge case 3: boundary values
        java.math.BigDecimal zero = java.math.BigDecimal.ZERO;
        java.math.BigDecimal negativeBalance = new java.math.BigDecimal("-0.01");
        System.out.println(zero.compareTo(negativeBalance) > 0);  // true
    }
}
TEXT
Null account ID
true
false
true

Always test with null values, empty strings, boundary values, and negative amounts in banking applications.

What are common interview follow-up questions?

Interviewers often follow up with these related questions:

  • How does this concept apply to a high-throughput banking transaction system?
  • What are the performance implications in a production environment?
  • How would you debug issues related to this concept?
  • What tools would you use to monitor this in production?
  • How does this behave differently in Java 8 vs Java 17+?

When answering follow-up questions, always relate your answer back to practical experience. For example, at National Bank of India, Rajesh debugged a production issue related to this concept by using JFR recordings and heap dumps. Providing concrete examples from banking systems shows the interviewer that you understand both the theory and the practice.

Visual Overview

DIAGRAM
  Class loading delegation chain:

  Application ClassLoader  (your classes)
    │ delegates to
    ▼
  Platform ClassLoader  (java.sql, javax)
    │ delegates to
    ▼
  Bootstrap ClassLoader  (java.lang, java.util)
    │
    ▼
  Found? → load. Not found? → parent not found → child tries → ClassNotFoundException

Key Takeaway

A class loader reads .class bytecode and loads it into JVM memory. Three built-in loaders form a chain: Bootstrap loads core JDK classes, Platform loads extensions, Application loads your code. Classes are loaded lazily on first use.

One sentence to remember: Bootstrap loads core Java, Platform loads extensions, Application loads your code – classes are loaded lazily on first use.

---

Share
Use ← → arrow keys to navigate