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