Ahmed Raaj
Ahmed Raaj

Reputation: 518

java class.forClass() vs Class declaration

I have one class Student which is

package org.ahmed;

public class Student {

    public Student() {
        // TODO Auto-generated constructor stub
        System.out.println("Generated constructor");
    }

    static { // static block
        System.out.println("Hello world static");
    }

    { // insance block
        System.out.println("Hello world non static");
    }
}

and then

public class Main {

    public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("org.ahmed.Student"); // this line causing static block execution in Student class
        // Student s; // this line doesn't execute the static block.
    }
}

I understand by using Class.forClass() we can dynamically run any class in runtime. But I have some question in other case regarding static block.

If I use Class.forClass("org.ahmed.Student") in my main method, then it's executing the static block of Student. But if I declare Student s in main method its doesn't execute the static block. I thought Class.forClass("ClassName") is same as declaring class with a variable name.

Upvotes: 1

Views: 2559

Answers (4)

eparvan
eparvan

Reputation: 1729

From javadoc:

Invoking Class.forName(className) method is equivalent to: Class.forName(className, true, currentLoader), where the second parameter specifies whether or not the class will be initialized.

So if you don't want to initialize the class, just call the method with initialize = false, e.g:

Class.forName("org.ahmed.Student", false, this.getClass().getClassLoader())}

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1075597

There's a distinction between loading a class (JLS§5.3 and, I think, JLS§5.4) and initializing a class (JLS§5.5). By default, Class.forName does both, although there's an override you can use that lets you control whether to initialize the class.

Just declaring a Student variable doesn't initialize the class. In fact, even referring to Student.class doesn't initialize the class. You must do something to trigger initialization, such as something that uses the new, getstatic, putstatic, or invokestatic bytecode operations with the class (but see the link to §5.5 for details, there are other things that initialize the class).

So for instance, if you gave Student a public field:

public static String foo = "bar";

...and then in Main.main you did:

System.out.println(Student.foo);

...that would trigger initialization of the class.

Upvotes: 3

Gal Dreiman
Gal Dreiman

Reputation: 4009

When you use Class.forName("org.ahmed.Student") you actually force the JVM to load the class and invoke its static blocks. You can read more here.

Upvotes: 2

snofty
snofty

Reputation: 70

Declaring the class references loads the class to JVM hence static block will be executed. i'm able to see static block execution on

Student s;

Example:

package com.snofty.test;

public class ClassLoading {

public ClassLoading(){
    System.out.println("in constructor");
}
static {
    System.out.println("in static block");
}

{
    System.out.println("in instance block");
}
public static void main(String[] args) {
    ClassLoading classLoading;

}

}

Class.forName()

it is used to load the class dynamically by passing the class name for example

public void loadClass(String className){
    Class.forName(className);
}

Upvotes: -1

Related Questions