前言
相信大家在使用反射操作時多多少少能用到這個方法。如果你使用了mysql資料庫并且使用了原生的資料庫操作,你肯定有一段這樣的代碼
Class.forName("com.mysql.jdbc.Driver");
這段代碼的意義就是生成一個代表com.mysql.jdbc.Driver類的java.lang.Class對象到記憶體中,作為方法區這個類的各種資料的入口,在執行初始化操作時調用該類靜态代碼塊。
檢視
com.mysql.jdbc.Driver
類
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
//
// Register ourselves with the DriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
/**
* Construct a new driver and register it with DriverManager
*
* @throws SQLException
* if a database error occurs.
*/
public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
}
在Driver類中有一個靜态代碼塊,在執行
Class.forName("com.mysql.jdbc.Driver");
會執行該代碼塊,做的就是注冊驅動,這樣在後續的
DriverManager.getConnection
操作才能使用我們的驅動來擷取資料庫連接配接。
使用class.forName
使用
class.forName
方法本質上做的就是類的加載。
類的加載分為:
加載、驗證、準備、解析、初始化、使用、解除安裝。
class.forName有兩個重載方法
forName(String className)
forName(String name, boolean initialize,ClassLoader loader)
- 通過子類引用父類的靜态字段,隻會觸發父類的初始化,而不會觸發子類的初始化。
- 定義對象數組,不會觸發該類的初始化。
- 常量在編譯期間會存入調用類的常量池中,本質上并沒有直接引用定義常量的類,不會觸發定義常量所在的類。
- 通過類名擷取Class對象,不會觸發類的初始化。
- 通過Class.forName加載指定類時,如果指定參數initialize為false時,也不會觸發類初始化,其實這個參數是告訴虛拟機,是否要對類進行初始化。
- 通過ClassLoader預設的loadClass方法,也不會觸發初始化動作。