Class.forName(String,false,loader)初始化设置为false,结果还是初始化执行了静态代码?

都说
Class.forName(String name, boolean initialize,ClassLoader loader)方法可以选择在加载类的时候是否要对类进行初始化
可是当我设置initialize为false的时候,结果还是执行了类里面的静态代码块,是为什么呢?

public class StringL {
    static {
        System.out.println("执行了静待代码块");
    }
    public static void main(String[] args){

        ClassLoader loader = ClassLoader.getSystemClassLoader();
        try {
            Class sample3=Class.forName("StringL",false,loader);
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }
}
阅读 3.8k
4 个回答

可能因为你这个StringL类 包括了入口main函数,说明一开始就已经被加载了。
所以就执行了静态代码块

你要执行main函数就得先加载StringL

执行main方法时,虚拟机调用 ClassLoader的方法进行累加载
public Class<?> loadClass(String name) throws ClassNotFoundException;
debug你会发现StringL这个类被加载了,接着调用LauncherHelper的方法进行较验
public static Class<?> checkAndLoadMain(boolean var0, int var1, String var2);
接下来初始化,执行静态代码块,最后执行main方法里面的代码,

执行过程大致是:
类加载->较验->准备(给静态变量分配空间)->解析->初始化->执行

如果将静态代码块放到SignUtils,就不会执行了,类只有在被用到的时候才会被加载
public class StringL {
    public static void main(String[] args) {
        ClassLoader loader = ClassLoader.getSystemClassLoader();
        try {
            Class sample3=Class.forName("com.framework.utils.SignUtils",false,loader);
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }
}

因为你的main函数是属于StringL这个类的,在执行这个main函数之前,StringL类已经初始化了。(因为在访问类的非final的静态域或者是静态函数会导致类的初始化!)如果你这里加载的不是启动类(这个带main函数的类),而是别的类,那么结果就和你想的一样了!

推荐问题