When Do Java Class Objects Differ? Exploring Three Ways to Get Class Instances

This article compares three common Java techniques—using the class literal, Class.forName, and an object's getClass method—to obtain a Class object, demonstrating their distinct effects on class loading, static initialization, and instance creation through detailed code examples and test results.

Senior Brother's Insights
Senior Brother's Insights
Senior Brother's Insights
When Do Java Class Objects Differ? Exploring Three Ways to Get Class Instances

In this article we compare three common ways to obtain a Class object in Java—using the class literal ( Person.class), Class.forName(...), and new Person().getClass() —and show how they differ in class loading and initialization.

Scenario 1: Basic behavior

We define a Person class that contains a static initializer, an instance initializer, and a constructor, each printing a message.

public class Person {
    static {
        System.out.println("Person:静态代码块");
    }
    {
        System.out.println("Person:动态代码块");
    }
    public Person() {
        System.out.println("Person:构造方法");
    }
}

A JUnit test class calls the three retrieval methods:

public class GetClassTest {
    @Test
    public void test1() {
        Class<?> clz = Person.class;
    }
    @Test
    public void test2() throws ClassNotFoundException {
        Class<?> clz = Class.forName("com.choupangxia.reflect.Person");
    }
    @Test
    public void test3() {
        Class<?> clz = new Person().getClass();
    }
}

Running the tests shows: test1 prints nothing because the class literal does not trigger any initializer. test2 prints only the static block, because Class.forName loads the class and executes static initializers. test3 prints the static block, the instance block, and the constructor message, since creating an object forces full initialization.

Scenario 2: Combining the calls

We invoke the three methods sequentially in a single test:

@Test
public void test4() throws ClassNotFoundException {
    Class<?> clz = Person.class;
    System.out.println("---------------");
    clz = Class.forName("com.choupangxia.reflect.Person");
    System.out.println("---------------");
    clz = new Person().getClass();
}

The output demonstrates that the static block runs only once, even though Class.forName is called after the class literal.

---------------
Person:静态代码块
---------------
Person:动态代码块
Person:构造方法

A similar test that starts with new Person().getClass() followed by Class.forName also shows a single execution of the static block, confirming that static initialization occurs only on the first load.

Scenario 3: Equality of the obtained Class objects

We compare the references returned by the three approaches:

@Test
public void test6() throws ClassNotFoundException {
    Class<?> clz1 = Person.class;
    Class<?> clz2 = Class.forName("com.choupangxia.reflect.Person");
    Class<?> clz3 = new Person().getClass();

    System.out.println(clz1 == clz2);
    System.out.println(clz2 == clz3);
}

The test prints true for both comparisons, indicating that all three methods return the same Class instance stored in the JVM.

Why the results are the same

Java’s class loading consists of loading, linking, and initialization phases. During loading, the bytecode is read and a single java.lang.Class object is created in the heap. For a given classloader, only one Class object exists, regardless of how many times the class is referenced.

Consequently: ClassName.class loads the class (if not already loaded) but does not trigger initialization. Class.forName("ClassName") loads and initializes the class, executing static initializers. instance.getClass() forces both loading and full initialization because an object instance is created.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaJVMReflectionunit testingclass loading
Senior Brother's Insights
Written by

Senior Brother's Insights

A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.