本文介紹了Java虛擬機(Java SE 11版本)加載類和接口。java
加載是指查找具備特定名稱的類或接口類型的二進制形式的過程。典型的作法是,查找事先由Java編譯器從源代碼計算而來二進制表示,但也多是經過動態計算。 二進制形式最終會構形成一個Class對象。git
加載的精確語義在Java Java Machine Specification,Java SE 11 Edition的第5章中給出。在這裏,咱們從Java編程語言的角度概述了該過程。github
類或接口的二進制格式一般是上面引用的Java虛擬機規範Java SE 11版中描述的類文件格式,但只要知足第13.1節中規定的要求,其餘格式也是可能的。編程
類ClassLoader的方法defineClass可用於從類文件格式的二進制表示構造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。jvm
加載過程由類ClassLoader及其子類實現。編程語言
ClassLoader的不一樣子類能夠實現不一樣的加載策略。特別地,類加載器能夠緩存類和接口的二進制表示,基於預期的使用來預取它們,或者將一組相關的類加載在一塊兒。 例如,若是找不到新編譯的類,由於舊版本由類加載器緩存,這些活動可能對正在運行的應用程序不徹底透明。可是,類加載器的責任是僅在程序中可能出現的狀況下反映加載錯誤,而無需預取或組加載。函數
若是在類加載期間發生錯誤,那麼將在程序中(直接或間接)使用該類型的任何點拋出類LinkichError的如下子類之一的實例:
由於加載涉及新數據結構的分配,因此它可能會因OutOfMemoryError而失敗。