Class Object

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 5 min

TL;DR

  • In Java, java.lang.Class is a special object that holds the metadata (the blueprint) of a loaded class.
  • For every type in Java (classes, interfaces, primitives, arrays), the JVM creates exactly one Class object when it is loaded into memory.
  • It is the entry point for all Reflection API operations.

Concept

When you write public class Car { ... } and compile it, you get Car.class.
When you run your program, the Java ClassLoader loads Car.class into the JVM’s Metaspace. At that exact moment, the JVM creates a special metadata object of type Class<Car>.

This Class object contains the entire blueprint of Car: what methods it has, what fields it has, what interfaces it implements, and what annotations are attached to it.
To use Reflection, you first need to get your hands on this Class object.

Three ways to get a Class Object

  1. Object instance: myCar.getClass()
  2. Class literal: Car.class
  3. String name (Dynamic): Class.forName("com.example.Car")

Examples

public class ClassObjectDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        
        // Method 1: If you already have an instance
        String text = "Hello";
        Class<?> class1 = text.getClass();
        
        // Method 2: If you know the type at compile time
        Class<?> class2 = String.class;
        
        // Method 3: If you only have the fully qualified name as a String at runtime
        // (This throws ClassNotFoundException if the class doesn't exist)
        Class<?> class3 = Class.forName("java.lang.String");
        
        // Because the JVM only ever creates ONE Class object per type, they are all the same!
        System.out.println(class1 == class2); // true
        System.out.println(class2 == class3); // true
        
        // Using the Class object to get metadata
        System.out.println("Class Name: " + class1.getName());
        System.out.println("Is Interface? " + class1.isInterface());
        System.out.println("Is Array? " + class1.isArray());
    }
}

Interview Questions

Q: What happens when you call Class.forName("com.example.Driver")?
A: It instructs the ClassLoader to search the classpath for a file named com.example.Driver.class. If found, it loads it into memory and returns its Class object. Crucially, as a side-effect of loading the class, it executes any static { } initialization blocks within the Driver class. This was historically how JDBC drivers were registered (Class.forName("com.mysql.jdbc.Driver")), as their static blocks automatically registered them with the DriverManager.

Q: Can primitive types have a Class object?
A: Yes! Every primitive type has a corresponding Class object, which is useful when using reflection to find methods that take primitive arguments. You can access it using int.class, boolean.class, or void.class. (Note: int.class is NOT the same as Integer.class).