[TOC]
## 動態加載
Java程序在運行時并不一定被完整加載,只有當發現該類還沒有加載時,才去本地或遠程查找類的.class文件并驗證和加載;
當程序創建了第一個對類的靜態成員的引用(如類的靜態變量、靜態方法、構造方法——構造方法也是靜態的)時,才會加載該類。Java的這個特性叫做:動態加載。
### 一個類的初始化包括3個步驟
* 加載(Loading),由類加載器執行,查找字節碼,并創建一個Class對象(只是創建);
* 鏈接(Linking),驗證字節碼,為靜態域分配存儲空間(只是分配,并不初始化該存儲空間),解析該類創建所需要的對其它類的應用;
* 初始化(Initialization),首先執行靜態初始化塊static{},初始化靜態變量,執行靜態方法(如構造方法)。
根據java虛擬機規范,所有java虛擬機實現必須在每個類或接口被java程序首次主動使用時才初始化。
### 主動使用有以下6種:
* 創建類的實例
* 訪問某個類或者接口的靜態變量,或者對該靜態變量賦值(如果訪問靜態編譯時常量(即編譯時可以確定值的常量)不會導致類的初始化)
* 調用類的靜態方法
* 反射(Class.forName(xxx.xxx.xxx))
* 初始化一個類的子類(相當于對父類的主動使用),不過直接通過子類引用父類元素,不會引起子類的初始化(參見示例6)
* Java虛擬機被標明為啟動類的類(包含main方法的)
### Bootstrap CLassloder
由C++編寫的,它本身是虛擬機的一部分,所以它并不是一個JAVA類,也就是無法在java代碼中獲取它的引用
JVM啟動時通過Bootstrap類加載器加載rt.jar等核心jar包中的class文件,之前的int.class,String.class都是由它加載
Bootstrap沒有父加載器,但是它卻可以作為任何一個ClassLoader的父加載器。比如ExtClassLoader
這句話的理解,必須結合后文中的 loadClass()過程,也就是在雙親委托模型中向上迭代父加載器查找時,如果父加載器為null,則jvm內置的加載器去替代,也就是Bootstrap ClassLoader
### Extention ClassLoader
加載目錄%JRE\_HOME%\\lib\\ext目錄下的jar包和class文件。
### AppClassLoader
加載當前應用的classpath的所有類
java虛擬機的入口應用,sun.misc.Launcher
## 雙親委托
### loadClass的實現
(向下一直找緩存,向上找實現)
1. 一個AppClassLoader查找資源時,先看看緩存是否有,緩存有從緩存中獲取,否則委托給父加載器。
2. 遞歸,重復第1步的操作。
3. 如果ExtClassLoader也沒有加載過,則由Bootstrap ClassLoader出面。
4. Bootstrap ClassLoader首先查找緩存,如果沒有找到的話,就去找自己的規定的路徑下,也就是sun.mic.boot.class下面的路徑。找到就返回,沒有找到,讓子加載器自己去找
5. Bootstrap ClassLoader如果沒有查找成功,則ExtClassLoader自己在java.ext.dirs路徑中去查找,查找成功就返回,查找不成功,再向下讓子加載器找
6. ExtClassLoader查找不成功,AppClassLoader就自己查找,在java.class.path路徑下查找。找到就返回。如果沒有找到就讓子類找
7. 如果沒有子類會拋出各種異常
### 為什么要使用這種雙親委托模式呢?
* 【重復】因為這樣可以避免重復加載,當父親已經加載了該類的時候,就沒有必要子ClassLoader再加載一次。
* 【安全】考慮到安全因素,我們試想一下,如果不使用這種委托模式,那我們就可以隨時使用自定義的String.class來動態替代java核心api中定義類型,這樣會存在非常大的安全隱患,而雙親委托的方式,就可以避免這種情況,因為String.class已經在啟動時被加載,所以用戶自定義類是無法加載一個自定義的ClassLoade
自定義一個ClassLoader,默認加載路徑為D:\\lib下的jar包和資源
### NoClassDefFoundError和ClassNotFoundExceptiom
NoClassDefFoundError:當java源文件已編譯成.class文件,但是ClassLoader在運行期間在其搜尋路徑load某個類時,沒有找到.class文件則報這個錯
ClassNotFoundException:試圖通過一個String變量來創建一個Class類時不成功則拋出這個異常
- Java
- Object
- 內部類
- 異常
- 注解
- 反射
- 靜態代理與動態代理
- 泛型
- 繼承
- JVM
- ClassLoader
- String
- 數據結構
- Java集合類
- ArrayList
- LinkedList
- HashSet
- TreeSet
- HashMap
- TreeMap
- HashTable
- 并發集合類
- Collections
- CopyOnWriteArrayList
- ConcurrentHashMap
- Android集合類
- SparseArray
- ArrayMap
- 算法
- 排序
- 常用算法
- LeetCode
- 二叉樹遍歷
- 劍指
- 數據結構、算法和數據操作
- 高質量的代碼
- 解決問題的思路
- 優化時間和空間效率
- 面試中的各項能力
- 算法心得
- 并發
- Thread
- 鎖
- java內存模型
- CAS
- 原子類Atomic
- volatile
- synchronized
- Object.wait-notify
- Lock
- Lock之AQS
- Lock子類
- 鎖小結
- 堵塞隊列
- 生產者消費者模型
- 線程池