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

初探 Java 類別載入機制奧秘

     編輯:Java 相關知識

JDK 1.2+ 採雙親委派模型載入類別:ClassLoader 尋找不到類別時委派父載入器,根載入器為系統載入器(預設從本地檔案系統載入)。探討 JVM 內部運作機制。

ClassLoader 核心方法

  • loadClass(String, boolean):入口點,JDK 1.2+ 預設調用 findClass
  • defineClass(String, byte[], int, int):核心,將位元組碼解析為運行時資料結構、驗證有效性,final 不可覆寫
  • findSystemClass:從本地檔案系統載入
  • findClass:自訂載入邏輯入口,預設實作拋出 ClassNotFoundException
  • getSystemClassLoader、getParent:存取系統/父載入器
  • resolveClass:解析類別(視 loadClass 的 resolve 參數)
  • findLoadedClass:快取檢查,避免重複載入

載入工作流程

  1. 調用 findLoadedClass 檢查快取
  2. 委派父載入器 loadClass(父為 null 則用系統載入器)
  3. 調用 findClass 查找類別
  4. 若 resolve 為 true,調用 resolveClass
  5. 仍無類別則拋出 ClassNotFoundException
  6. 否則回傳 Class 物件

自訂 ClassLoader 實作範例:即時編譯載入器

CompilingClassLoader:檢查 .java 檔是否比 .class 新,若是則呼叫 javac 編譯,再以 defineClass 載入。測試類別 TestRun 使用反射呼叫載入類別的 main 方法。

// 核心 loadClass 邏輯
Class clas = findLoadedClass(name);
String fileStub = name.replace('.', '/');
File javaFile = new File(fileStub + ".java");
File classFile = new File(fileStub + ".class");
if (javaFile.exists() && (!classFile.exists() || javaFile.lastModified() > classFile.lastModified())) {
    compile(javaFile); // 呼叫 javac
}
byte[] raw = getBytes(classFile.getPath());
clas = defineClass(name, raw, 0, raw.length);
if (clas == null) clas = findSystemClass(name);
if (resolve && clas != null) resolveClass(clas);

測試執行

編譯 CompilingClassLoader、TestRun,撰寫簡單 Hello.java,執行 java TestRun Hello 參數,輸出 Hello,參數,驗證自訂載入器運作。

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