Java面試基礎篇——第十一篇:Class.forName和ClassLoader的區別

Java中的Class.forName()ClassLoader均可以用來對類進行加載。Class.forName()除了將類的.class文件加載到JVM中 還會對類進行解釋,執行類中的static塊,而ClassLoader只會將.class文件加載到JVM,不會執行static塊,只有在newInstance的時候才執行static塊。Class.forName(name, initialize, loader)帶參函數也可控制是否加載static塊。而且只有調用了newInstance()方法纔會調用構造函數,建立類的對象。java

來看看Class.forName()的源碼spring

@CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        Class<?> caller = Reflection.getCallerClass();
		//第二個參數 true,表示是否初始化,初始化就是執行static代碼
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }

OK, 到這咱們來作個小小的測試mvc

public class Main {

    private static final String CLASS_NAME_1 = "com.developlee.springmvclearn.test.Test";
    private static final String CLASS_NAME_2 = "com.developlee.springmvclearn.test.Test2";

    public static void main(String[] args) throws Exception {

        testClassLoader(CLASS_NAME_1, CLASS_NAME_2);
        System.out.println("上面測試ClassLoader 下面測試Class.forName()");
        testClassForName(CLASS_NAME_1, CLASS_NAME_2);

    }

    private static void testClassLoader(String class1, String class2){
        Class<?> clazz1;
        Class<?> clazz2;
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        try {
            clazz1 = classLoader.loadClass(class1);
            clazz2 = classLoader.loadClass(class2);
            System.out.println("Class1: " + clazz1.getSimpleName() + ", Class2: " + clazz2.getSimpleName());
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private static void testClassForName(String class1, String class2){
        try {
            Class clazz1 = Class.forName(class1);
            Class clazz2 = Class.forName(class2);
            System.out.println("Class1: " + clazz1.getSimpleName() + ", Class2: " + clazz2.getSimpleName());
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

Test和Test2的代碼函數

public class Test {
    static {
        System.out.println("靜態代碼塊執行了...");
    }

}

public class Test2 {
    static {
        System.out.println("Test2 static code blocks is running !");
    }
}

看看執行的結果測試

Class1: Test, Class2: Test2
上面測試ClassLoader 下面測試Class.forName()
靜態代碼塊執行了...
Test2 static code blocks is running !
Class1: Test, Class2: Test2

Process finished with exit code 0

發現ClassLoader並不會執行static代碼塊,而Class.forName()纔會執行對類的初始化,這也就驗證了文章開始咱們所闡述的觀點。code

相關文章
相關標籤/搜索