1. 程式人生 > >JVM(Java SE 11版本)載入類和介面

JVM(Java SE 11版本)載入類和介面

本文介紹了Java虛擬機器(Java SE 11版本)載入類和介面。

載入類和介面

載入是指查詢具有特定名稱的類或介面型別的二進位制形式的過程。典型的做法是,查詢事先由Java編譯器從原始碼計算而來二進位制表示,但也可能是通過動態計算。
二進位制形式最終會構造成一個Class物件。

載入的精確語義在Java Java Machine Specification,Java SE 11 Edition的第5章中給出。在這裡,我們從Java程式語言的角度概述了該過程。

類或介面的二進位制格式通常是上面引用的Java虛擬機器規範Java SE 11版中描述的類檔案格式,但只要滿足第13.1節中規定的要求,其他格式也是可能的。

類ClassLoader的方法defineClass可用於從類檔案格式的二進位制表示構造Class物件。

表現良好的類載入器維護這些性質:

  • 給定相同的名稱,一個好的類載入器應該總是返回相同的類物件。
  • 如果類載入器L1將類C的載入委託給另一個載入器L2,那麼對於作為直接超類或C的直接超接口出現的任何型別T,或作為C中的欄位型別,或作為型別方法的正式引數或
    C中的建構函式,或者作為C,L1和L2中方法的返回型別應該返回相同的Class物件。

惡意類載入器可能違反這些性質。但是,它不能破壞型別系統的安全性,因為Java虛擬機器可以防範這種情況。

有關這些問題的進一步討論,請參閱Java虛擬機器規範,Java SE 11版和Java虛擬機器中的動態類載入,作者:Sheng Liang和Gilad Bracha,作為ACO SIGPLAN釋出的OOPSLA '98會議錄。通告,第33卷,第10期,1998年10月,第36-44頁。Java程式語言設計的基本原則是執行時型別系統不能被用Java程式語言編寫的程式碼破壞,即使是這樣的實現也是如此。否則敏感的系統類如ClassLoader和SecurityManager。

載入過程

載入過程由類ClassLoader及其子類實現。

ClassLoader的不同子類可以實現不同的載入策略。特別地,類載入器可以快取類和介面的二進位制表示,基於預期的使用來預取它們,或者將一組相關的類載入在一起。
例如,如果找不到新編譯的類,因為舊版本由類載入器快取,這些活動可能對正在執行的應用程式不完全透明。但是,類載入器的責任是僅在程式中可能出現的情況下反映載入錯誤,而無需預取或組載入。

如果在類載入期間發生錯誤,那麼將在程式中(直接或間接)使用該型別的任何點丟擲類LinkichError的以下子類之一的例項:

  • ClassCircularityError:無法載入類或介面,因為它將是自己的超類或超介面(第8.1.4節,第9.1.3節,第13.4.4節)。
  • ClassFormatError:聲稱指定所請求的編譯類或介面的二進位制資料格式錯誤。
  • NoClassDefFoundError:相關類載入器無法找到所請求的類或介面的定義。

因為載入涉及新資料結構的分配,所以它可能會因OutOfMemoryError而失敗。

參考引用