當我們使用new操作符創建一個類的instace,它做了兩件事
- 加載類到內存中,如果沒有加載它 - 這意味着創建內存之類的表示從.class文件中刪除,以便可以創建一個實例。這包括初始化靜態變量(解析該類)
- 創建該類的實例並存儲對該變量的引用。
Class.forName
只做第一件事。 它將類加載到內存中,並將該引用作爲Class的實例返回。如果我們想創建一個實例,那麼我們可以調用該類的newInstance方法。這將調用默認的構造函數(無參數構造函數)。 請注意,如果默認構造函數不可訪問,則newInstance方法將拋出一個IllegalAccessException
。如果這個類是一個抽象類或接口,或者它沒有默認構造函數,那麼它將拋出InstantiationException
。如果在解決該課程時出現任何異常情況,則會拋出一個ExceptionInInitializerError
。
如果未定義默認構造函數,那麼我們必須使用反射API調用defiend構造函數。
但是,Class.forName的主要優點是,它可以接受類名作爲String參數。所以我們可以動態地傳遞類名。但是,如果我們使用new運算符創建類的實例,則不能動態更改類名稱。
Class.forName()
inturn將調用調用方ClassLoader的loadClass方法(調用Class.forName
的類的ClassLoder)。
默認情況下,Class.forName()
解析該類。這意味着,初始化該類中的所有靜態變量。 同樣可以使用過載方法Class.forName(String name,boolean initialize,ClassLoader loader)
使用Class.forName()
加載jdbc驅動程序的主要原因是,驅動程序可以動態更改。 在靜態塊中,所有的驅動程序都將創建一個自己的實例,並使用DriverManager.registerDriver()
方法向DriverManager註冊該類。由於Class.forName(String className)
默認解析類,它會初始化靜態初始化器。 所以當我們調用Class.forName("com.sun.jdbc.odbc.JdbcOdbcDriver")
, Driver類會被加載,實例化,並與DriverManager的
註冊
所以,如果你正在使用新的操作你必須做以下的事情。
代碼:
Driver drv = new com.sun.jdbc.odbc.JdbcOdbcDriver();
DriverManager.registerDriver(drv);
另見http://stackoverflow.com/a/8053125/632951 – Pacerier 2014-08-24 22:44:07