结论及原因
- 结论:Java调用静态方法时会对类进行装载、连接和初始化
- 原因:Java类的加载方式是按需加载,遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令的最常见的Java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
测试
-
参照之前写的一篇文章,得出的测试思路:
- 对一个有静态方法和静态代码块的类只进行装载,不进行初始化
- 通过反射获取其静态方法,并invoke这个静态方法
- 因为静态代码块在初始化的时候执行,所以如果invoke这个静态方法的时候,静态代码块执行了,说明了Java调用静态方法时已经完成了类的初始化
-
有一个含有static方法和static块的类
class MyStatic {
static {
System.out.println("静态代码块执行了");
}
public static void say() {
System.out.println("静态方法执行了");
}
MyStatic() {}
}
- 测试
public class Test {
Test() {}
public static void main(String[] args) {
Test test = new Test();
try{
Class clazz = Class.forName("MyStatic", false, test.getClass().getClassLoader());
Method method = clazz.getMethod("say");
method.invoke(null);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
-
控制台打印的结果:
静态代码块执行了
静态方法执行了
以上