反射中Class.forName()和ClassLoader.loadClass()的區別


一 Java類裝載過程

復制代碼
裝載:通過累的全限定名獲取二進制字節流,將二進制字節流轉換成方法區中的運行時數據結構,在內存中生成Java.lang.class對象; 

鏈接:執行下面的校驗、准備和解析步驟,其中解析步驟是可以選擇的; 

  校驗:檢查導入類或接口的二進制數據的正確性;(文件格式驗證,元數據驗證,字節碼驗證,符號引用驗證) 

  准備:給類的靜態變量分配並初始化存儲空間; 

  解析:將常量池中的符號引用轉成直接引用;
初始化:激活類的靜態變量的初始化Java代碼和靜態Java代碼塊,並初始化程序員設置的變量值。
復制代碼

二 分析 Class.forName()和ClassLoader.loadClass

    

復制代碼
Class.forName(className)方法,內部實際調用的方法是  Class.forName(className,true,classloader);

第2個boolean參數表示類是否需要初始化,  Class.forName(className)默認是需要初始化。

一旦初始化,就會觸發目標對象的 static塊代碼執行,static參數也也會被再次初始化。 ClassLoader.loadClass(className)方法,內部實際調用的方法是 ClassLoader.loadClass(className,false); 第2個 boolean參數,表示目標對象是否進行鏈接,false表示不進行鏈接,由上面介紹可以,

不進行鏈接意味着不進行包括初始化等一些列步驟,那么靜態塊和靜態對象就不會得到執行
復制代碼



三  數據庫鏈接為什么使用Class.forName(className)

 

JDBC  Driver源碼如下,因此使用Class.forName(classname)才能在反射回去類的時候執行static塊。

復制代碼
static {
    try {
        java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
        throw new RuntimeException("Can't register driver!");
    }
}
復制代碼

 參考鏈接:https://www.cnblogs.com/zabulon/p/5826610.html

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM