類加載器的作用
將classpath中的.class字節碼文件加載進虛擬機
類加載器之間的關係和管轄範圍
java虛擬機中可以安裝多個類加載器,系統默認主要三個類加載器,每個類加載器負責加載特定位置的類:
BootStrap,ExtClassLoader,AppClassLoader
類加載器也是java類,因爲其他是java類的類加載器本身也要被類加載器加載,顯然必須有第一個類加載器不是java類,這正是BootStrap,用C++寫的,是嵌入在java虛擬機中的類加載器。
類加載器的委託機制
我們可以寫一個自己的類加載器,然後掛在它的父類加載器上。
當某一個類在某個類加載器的範圍內時,這個類加載器不會立即加載它,而是將其交給它的父類加載器,如果它的父類加載器找不到這個類,則將其推給父加載器的父加載器,如果找到了,則好。找不到則再推給它的兒子加載器,然後它的兒子加載器推給它自己的兒子加載器,如果加載到了,則好,還是加載不到,則拋異常。
自定義類加載器
必須繼承抽象類ClassLoader,並且覆蓋findClass()方法。
類加載器中涉及loadClass()、findClass()、defineClass()三個方法。
大致的執行過程如下:
loadClass()方法定義了類加載器的委託機制的流程,所以我們自定義類加載的時候,不要去覆蓋它,我們利用它的流程,因爲我們要保持類加載器的委託機制,我們只需要
覆蓋findClass()方法,這個方法定義了我們自己的類加載的加載過程。loadClass()方法的邏輯就是先交給父類加載器,找不到再交給子加載器,所以它最後會調用findClass()。
類加載器中的設計模式
類加載器採用了模板方法設計模式。
類加載器的工作原理
.javac將java文件編譯成.class文件,類加載器通過findClass()方法將.class文件中的內容讀取成byte[] ,再通過defineClass()將字節數組讀成Class對象(字節碼),並將其加載進java虛擬機。只有加載進虛擬機的字節碼對象才能被解析執行。所以任何一個類似"對象.方法"的執行原理都是這樣,首先必須將這個對象完成上述過程,才能執行相應的行爲。
類加載器的高級分析
父級類加載器加載的類無法引用只能被子級類加載器加載的類
tomcat類加載器的關係