天天看點

關于Class.forName

前言

相信大家在使用反射操作時多多少少能用到這個方法。如果你使用了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方法,也不會觸發初始化動作。