首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 類加載器全解析:雙親委派、可見性、沙箱機制與自定義實戰

     編輯:Java 相關知識

類加載器核心三大機制

機制含義作用
雙親委派加載請求先委派給父加載器,父無法加載時子才嘗試保證核心類庫統一、防止惡意覆蓋、避免重複加載
可見性父加載器加載的類對子可見,子加載的類父不可見實現命名空間隔離,基礎類庫共享
單一性同一類加載器實例下,同一全限定名類只加載一次保證運行時類唯一性

系統默認三大類加載器

Bootstrap ClassLoader (啟動類加載器)
    ↑ C++ 實現,非 Java 類,加載 /jre/lib/rt.jar 等核心庫
Extension ClassLoader (擴展類加載器)
    ↑ Java 實現,加載 /jre/lib/ext/*.jar
Application ClassLoader (應用/系統類加載器)
    ↑ Java 實現,加載 classpath (-cp) 指定路徑,getClassLoader() 返回此對象

String.class.getClassLoader() == null 證明核心類由 Bootstrap 加載。

類加載流程:loadClass() 模板方法


protected Class<?> loadClass(String name, boolean resolve) {
    synchronized (getClassLoadingLock(name)) {
        Class<?> c = findLoadedClass(name); // 1. 緩存檢查
        if (c == null) {
            try {
                if (parent != null) c = parent.loadClass(name, false); // 2. 委派父加載
                else c = findBootstrapClassOrNull(name); // 3. 委派 Bootstrap
            } catch (ClassNotFoundException ignored) {}
            if (c == null) c = findClass(name); // 4. 自己查找 (子類實現)
        }
        if (resolve) resolveClass(c); // 5. 連接 (可選)
        return c;
    }
}

自定義類加載器實戰:網絡加載


class NetworkClassLoader extends ClassLoader {
    private String host; private int port;
    @Override protected Class<?> findClass(String name) {
        byte[] data = loadClassData(name); // 從網絡讀取 .class 字節碼
        return defineClass(name, data, 0, data.length); // 定義為 Class 對象
    }
    private byte[] loadClassData(String name) { /* HTTP 下載邏輯 */ }
}

關鍵點:只需覆寫 findClass(),**不要覆寫 loadClass()** 除非打破雙親委派(如熱部署、模塊化框架)。

打破雙親委派的經典場景

  • Tomcat:WebappClassLoader 優先自加載 WAR 包類,隔離不同應用
  • OSGi:模塊化動態加載,多版本共存
  • JDBC SPI:線程上下文類加載器 (Thread.currentThread().getContextClassLoader()) 反向加載服務實現
  • 熱部署/熱替換:自定義加載器卸載舊類、加載新類

常見面試陷阱

  1. 類加載器也是類,由父加載器加載(Bootstrap 除外)
  2. 同名類不同加載器加載 = 不同類,instanceof、強轉、靜態字段均不共享
  3. 類主動使用 vs 被動使用:只有主動使用觸發初始化 (<clinit>)

總結

類加載器是 Java 動態性的基石。**雙親委派保安全,可見性做隔離,單一性保唯一**。理解源碼 loadClass 模板方法,掌握 findClass 覆寫點,才能驾驭熱部署、模塊化、多版本共存等高級場景。**除非框架開發,業務代碼極少自定義類加載器。**

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved