java中class.forName和classLoader都可用來對類進行加載。前者除了將類的.class文件加載到jvm中之外,還會對類進行解釋,執行類中的static塊。而classLoader只干一件事情,就是將.class文件加載到jvm中,不會執行static中的內容,只有在newInstance才會去執行static塊(網上有很多文章說,static塊在類第一次被加載是執行,是錯誤的,比如這個人的博客:https://yq.aliyun.com/articles/58333)。
我們可以通過一個小例子來驗證一下:
class MyClass1 { static {//靜態塊 System.out.println("static block "); } } public class Main { Class[] classArray = { MyClass1.class//這樣引用該類,必然需要將該類加載到虛擬機中 }; public static void main(String[] args){ System.out.println("hello word"); } }
執行結果:並沒有輸出" static bolck"
Class.forName(name, initialize, loader)帶參函數也可控制是否加載static塊。並且只有調用了newInstance()方法采用調用構造函數,創建類的對象 。比如:
Static Class forName(String name, boolean initialize, ClassLoader loader)
將 initialize 設定為 false,這樣在加載類時並不會立即運行靜態區塊,而會在使用類建立對象時才運行靜態區塊。
其實當你調用Class.forName("classname")的時候相當於:
Class.forName("classname",true,this.getClass().getClassLoader());
什么情況下使用class.forname?
在一些應用中,無法事先知道使用者將加載什么類,而必須讓使用者指定類名稱以加載類,可以使用 Class 的靜態 forName() 方法實現動態加載類。下面的范例讓你可以指定類名稱來獲得類的相關信息。例如我們最熟悉的數據庫驅動就是通過顯示的class.forname來夾在數據庫驅動類的,因為jvm啟動的時候根本不知道你需要加在mysql的驅動包還是sqlserver的數據庫驅動包。
/* 連接mysql 時裝載的驅動類以及連接字符串 */ Class.forName(“com.mysql.jdbc.Driver”);//1 DriverManager.getConnection(“jdbc:mysql://localhost:3306/test”,”root”,”123”);//2 /* 連接SQLServer2005 時裝載的驅動類以及連接字符串 */ Class.forName(“com.microsoft.sqlserver.jdbc.SQLServerDriver”); DriverManager.getConnection(“jdbc:sqlserver://localhost:1433;databaseName=pubs”,”sa”, ””);
引用:http://blog.csdn.net/u011202334/article/details/51497998
http://blog.csdn.net/berber78/article/details/46472789