java class.forClass()vs类声明

时间:2016-11-24 08:14:38

标签: java reflection

我有一个班级学生

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");
    }
}

然后

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.
    }
}

我理解使用Class.forClass()我们可以动态运行任何 运行时的类。但在其他情况下,我有一些问题 静态阻止。

如果我在Class.forClass("org.ahmed.Student")方法中使用main,那么就是这样 执行Student的静态块。但如果我宣布Student s main方法不会执行静态块。我想 Class.forClass("ClassName")与使用变量声明类相同 名。

4 个答案:

答案 0 :(得分:3)

加载类(JLS§5.3,我认为JLS§5.4)和初始化类({{3} })。默认情况下,Class.forName同时执行这两项操作,但JLS§5.5允许您控制是否初始化类。

仅声明Student变量不会初始化类。实际上,即使引用Student.class也不会初始化类。您必须执行某些操作才能触发初始化,例如对类使用newgetstaticputstaticinvokestatic字节码操作的内容(但请参阅§的链接) 5.5有关详细信息,还有其他事情初始化类。)

例如,如果您给Student公共字段:

public static String foo = "bar";

...然后在Main.main你做了:

System.out.println(Student.foo);

... 会触发类的初始化。

答案 1 :(得分:2)

使用Class.forName("org.ahmed.Student")时,实际上强制JVM加载类并调用其静态块。您可以阅读更多here

答案 2 :(得分:1)

来自javadoc

  

调用Class.forName(className)方法是   等价于:Class.forName(className, true, currentLoader),其中第二个参数指定是否将初始化类。

因此,如果您不想初始化该类,只需使用initialize = false调用该方法,例如:

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

答案 3 :(得分:-1)

声明类引用将类加载到JVM,因此将执行静态块。我能够在

上看到静态块执行
Student s;

示例:

package com.snofty.test;

公共类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()

它用于通过传递类名来动态加载类 例如

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