我有一个班级学生
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")
与使用变量声明类相同
名。
答案 0 :(得分:3)
加载类(JLS§5.3,我认为JLS§5.4)和初始化类({{3} })。默认情况下,Class.forName
同时执行这两项操作,但JLS§5.5允许您控制是否初始化类。
仅声明Student
变量不会初始化类。实际上,即使引用Student.class
也不会初始化类。您必须执行某些操作才能触发初始化,例如对类使用new
,getstatic
,putstatic
或invokestatic
字节码操作的内容(但请参阅§的链接) 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);
}