天天看點

JavaCore 【 Java中的Class.forName()和ClassLoader.loadClass()的差別】

類裝載順序

JavaCore 【 Java中的Class.forName()和ClassLoader.loadClass()的差別】

類加載過程

Class.forName()和ClassLoader.loadClass 對比

Class.forName(className)方法,内部實際調用的方法是Class.forName(className,true,classloader);

JavaCore 【 Java中的Class.forName()和ClassLoader.loadClass()的差別】

第2個boolean參數表示類是否需要初始化, Class.forName(className)預設是需要初始化。

JavaCore 【 Java中的Class.forName()和ClassLoader.loadClass()的差別】

一旦初始化,就會觸發目标對象的 static塊代碼執行,static參數也也會被再次初始化。

ClassLoader.loadClass(className)方法,内部實際調用的方法是 ClassLoader.loadClass(className,false);

JavaCore 【 Java中的Class.forName()和ClassLoader.loadClass()的差別】

第2個 boolean參數,表示目标對象是否進行連結,false表示不進行連結,由上面介紹可以,

JavaCore 【 Java中的Class.forName()和ClassLoader.loadClass()的差別】

舉個例子

JavaCore 【 Java中的Class.forName()和ClassLoader.loadClass()的差別】

實體類:

public class Person {

    public Person() {
        System.out.println("構造代碼塊");
    }

    static {
        System.out.println("靜态代碼塊!!!");
    }

    //靜态變量
    private static String staticFiled = staticMethod();

    //指派靜态變量的靜态方法
    public static String staticMethod(){
        System.out.println("執行了靜态方法");
        return "給靜态字段指派了";
    }

    public static String staticMethod2(){
        System.out.println("執行了靜态方法 2222");
        return "給靜态字段指派了222";
    }

    {
        System.out.println("普通的代碼塊");
    }


}
           

測試類:

public static void main(String[] args) {
        String PersionClassName = "com.jacky.thread.classloader.Person";
        System.out.println("==== Classloader =======");
        ClassLoader loader = ClassLoader.getSystemClassLoader();
        Class<?> personClassLoader;
        try {

            personClassLoader = loader.loadClass(PersionClassName);
            System.out.println("person  loadClass : " + personClassLoader.getName());

            System.out.println("===== ClassForName ======");
            Class personForName = Class.forName(PersionClassName);
            System.out.println("person  forName : " + personForName.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
           

輸出結果:

JavaCore 【 Java中的Class.forName()和ClassLoader.loadClass()的差別】

結果得出結論: ClassforName會對類初始化,也就是說會執行類中的靜态代碼塊,以及對靜态變量的指派等操作

總結

  • 整個類加載階段分五步:加載、驗證、準備、解釋、初始化。
  • ClassLoader :隻負責第一步加載,就是加載class到jvm記憶體中,沒有執行初始化操作
  • Class.forName :會執行類中的靜态代碼塊,以及對靜态變量的指派等操作。