---
title: ç±»å è½½å¨è¯¦è§£ï¼éç¹ï¼
category: Java
tag:
- JVM
---
## å顾ä¸ä¸ç±»å è½½è¿ç¨
å¼å§ä»ç»ç±»å è½½å¨ååäº²å§æ´¾æ¨¡åä¹åï¼ç®åå顾ä¸ä¸ç±»å è½½è¿ç¨ã
- ç±»å è½½è¿ç¨ï¼**å è½½->è¿æ¥->åå§å**ã
- è¿æ¥è¿ç¨åå¯åä¸ºä¸æ¥ï¼**éªè¯->åå¤->è§£æ**ã

å è½½æ¯ç±»å è½½è¿ç¨çç¬¬ä¸æ¥ï¼ä¸»è¦å®æä¸é¢ 3 ä»¶äºæ
ï¼
1. éè¿å
¨ç±»åè·åå®ä¹æ¤ç±»çäºè¿å¶åèæµ
2. å°åèæµæä»£è¡¨çéæåå¨ç»æè½¬æ¢ä¸ºæ¹æ³åºçè¿è¡æ¶æ°æ®ç»æ
3. å¨å
åä¸çæä¸ä¸ªä»£è¡¨è¯¥ç±»ç `Class` 对象ï¼ä½ä¸ºæ¹æ³åºè¿äºæ°æ®ç访é®å
¥å£
## ç±»å è½½å¨
### ç±»å è½½å¨ä»ç»
ç±»å è½½å¨ä» JDK 1.0 å°±åºç°äºï¼æååªæ¯ä¸ºäºæ»¡è¶³ Java Appletï¼å·²ç»è¢«æ·æ±°ï¼ çéè¦ãåæ¥ï¼æ
¢æ
¢æä¸º Java ç¨åºä¸çä¸ä¸ªéè¦ç»æé¨åï¼èµäºäº Java ç±»å¯ä»¥è¢«å¨æå è½½å° JVM ä¸å¹¶æ§è¡çè½åã
æ ¹æ®å®æ¹ API ææ¡£çä»ç»ï¼
> A class loader is an object that is responsible for loading classes. The class ClassLoader is an abstract class. Given the binary name of a class, a class loader should attempt to locate or generate data that constitutes a definition for the class. A typical strategy is to transform the name into a file name and then read a "class file" of that name from a file system.
>
> Every Class object contains a reference to the ClassLoader that defined it.
>
> Class objects for array classes are not created by class loaders, but are created automatically as required by the Java runtime. The class loader for an array class, as returned by Class.getClassLoader() is the same as the class loader for its element type; if the element type is a primitive type, then the array class has no class loader.
ç¿»è¯è¿æ¥å¤§æ¦çæææ¯ï¼
> ç±»å è½½å¨æ¯ä¸ä¸ªè´è´£å 载类ç对象ã`ClassLoader` æ¯ä¸ä¸ªæ½è±¡ç±»ãç»å®ç±»çäºè¿å¶åç§°ï¼ç±»å è½½å¨åºå°è¯å®ä½æçæææç±»å®ä¹çæ°æ®ãå
¸åççç¥æ¯å°å称转æ¢ä¸ºæä»¶åï¼ç¶åä»æä»¶ç³»ç»ä¸è¯»å该åç§°çâç±»æä»¶âã
>
> æ¯ä¸ª Java ç±»é½æä¸ä¸ªå¼ç¨æåå è½½å®ç `ClassLoader`ãä¸è¿ï¼æ°ç»ç±»ä¸æ¯éè¿ `ClassLoader` å建çï¼èæ¯ JVM å¨éè¦çæ¶åèªå¨å建çï¼æ°ç»ç±»éè¿`getClassLoader()`æ¹æ³è·å `ClassLoader` çæ¶åå该æ°ç»çå
ç´ ç±»åç `ClassLoader` æ¯ä¸è´çã
ä»ä¸é¢çä»ç»å¯ä»¥çåº:
- ç±»å è½½å¨æ¯ä¸ä¸ªè´è´£å 载类ç对象ï¼ç¨äºå®ç°ç±»å è½½è¿ç¨ä¸çå è½½è¿ä¸æ¥ã
- æ¯ä¸ª Java ç±»é½æä¸ä¸ªå¼ç¨æåå è½½å®ç `ClassLoader`ã
- æ°ç»ç±»ä¸æ¯éè¿ `ClassLoader` å建çï¼æ°ç»ç±»æ²¡æå¯¹åºçäºè¿å¶åèæµï¼ï¼æ¯ç± JVM ç´æ¥çæçã
```java
class Class {
...
private final ClassLoader classLoader;
@CallerSensitive
public ClassLoader getClassLoader() {
//...
}
...
}
```
ç®åæ¥è¯´ï¼**ç±»å è½½å¨ç主è¦ä½ç¨å°±æ¯å è½½ Java ç±»çåèç ï¼ `.class` æä»¶ï¼å° JVM ä¸ï¼å¨å
åä¸çæä¸ä¸ªä»£è¡¨è¯¥ç±»ç `Class` 对象ï¼ã** åèç å¯ä»¥æ¯ Java æºç¨åºï¼`.java`æä»¶ï¼ç»è¿ `javac` ç¼è¯å¾æ¥ï¼ä¹å¯ä»¥æ¯éè¿å·¥å
·å¨æçææè
éè¿ç½ç»ä¸è½½å¾æ¥ã
å
¶å®é¤äºå 载类ä¹å¤ï¼ç±»å è½½å¨è¿å¯ä»¥å è½½ Java åºç¨æéçèµæºå¦ææ¬ãå¾åãé
ç½®æä»¶ãè§é¢ççæä»¶èµæºãæ¬æåªè®¨è®ºå
¶æ ¸å¿åè½ï¼å 载类ã
### ç±»å è½½å¨å è½½è§å
JVM å¯å¨çæ¶åï¼å¹¶ä¸ä¼ä¸æ¬¡æ§å è½½ææçç±»ï¼èæ¯æ ¹æ®éè¦å»å¨æå è½½ãä¹å°±æ¯è¯´ï¼å¤§é¨åç±»å¨å
·ä½ç¨å°çæ¶åæä¼å»å è½½ï¼è¿æ ·å¯¹å
åæ´å å好ã
对äºå·²ç»å è½½çç±»ä¼è¢«æ¾å¨ `ClassLoader` ä¸ãå¨ç±»å è½½çæ¶åï¼ç³»ç»ä¼é¦å
夿å½åç±»æ¯å¦è¢«å è½½è¿ãå·²ç»è¢«å è½½çç±»ä¼ç´æ¥è¿åï¼å¦åæä¼å°è¯å è½½ãä¹å°±æ¯è¯´ï¼å¯¹äºä¸ä¸ªç±»å è½½å¨æ¥è¯´ï¼ç¸åäºè¿å¶åç§°çç±»åªä¼è¢«å è½½ä¸æ¬¡ã
```java
public abstract class ClassLoader {
...
private final ClassLoader parent;
// ç±è¿ä¸ªç±»å è½½å¨å è½½çç±»ã
private final Vector> classes = new Vector<>();
// ç±VMè°ç¨ï¼ç¨æ¤ç±»å è½½å¨è®°å½æ¯ä¸ªå·²å 载类ã
void addClass(Class> c) {
classes.addElement(c);
}
...
}
```
### ç±»å è½½å¨æ»ç»
JVM ä¸å
ç½®äºä¸ä¸ªéè¦ç `ClassLoader`ï¼
1. **`BootstrapClassLoader`(å¯å¨ç±»å è½½å¨)**ï¼æé¡¶å±çå 载类ï¼ç± C++å®ç°ï¼é常表示为 nullï¼å¹¶ä¸æ²¡æç¶çº§ï¼ä¸»è¦ç¨æ¥å è½½ JDK å
é¨çæ ¸å¿ç±»åºï¼ `%JAVA_HOME%/lib`ç®å½ä¸ç `rt.jar`ã`resources.jar`ã`charsets.jar`ç jar å
åç±»ï¼ä»¥å被 `-Xbootclasspath`åæ°æå®çè·¯å¾ä¸çææç±»ã
2. **`ExtensionClassLoader`(æ©å±ç±»å è½½å¨)**ï¼ä¸»è¦è´è´£å è½½ `%JRE_HOME%/lib/ext` ç®å½ä¸ç jar å
å类以å被 `java.ext.dirs` ç³»ç»åéææå®çè·¯å¾ä¸çææç±»ã
3. **`AppClassLoader`(åºç¨ç¨åºç±»å è½½å¨)**ï¼é¢åæä»¬ç¨æ·çå è½½å¨ï¼è´è´£å è½½å½ååºç¨ classpath ä¸çææ jar å
åç±»ã
> ð æå±ä¸ä¸ï¼
>
> - **`rt.jar`**ï¼rt 代表âRunTimeâï¼`rt.jar`æ¯ Java åºç¡ç±»åºï¼å
å« Java doc éé¢çå°çææçç±»çç±»æä»¶ãä¹å°±æ¯è¯´ï¼æä»¬å¸¸ç¨å
ç½®åº `java.xxx.* `é½å¨éé¢ï¼æ¯å¦`java.util.*`ã`java.io.*`ã`java.nio.*`ã`java.lang.*`ã`java.sql.*`ã`java.math.*`ã
> - Java 9 å¼å
¥äºæ¨¡åç³»ç»ï¼å¹¶ä¸ç¥å¾®æ´æ¹äºä¸è¿°çç±»å è½½å¨ãæ©å±ç±»å è½½å¨è¢«æ¹å为平å°ç±»å è½½å¨ï¼platform class loaderï¼ãJava SE ä¸é¤äºå°æ°å 个å
³é®æ¨¡åï¼æ¯å¦è¯´ `java.base` æ¯ç±å¯å¨ç±»å è½½å¨å è½½ä¹å¤ï¼å
¶ä»ç模ååç±å¹³å°ç±»å è½½å¨æå è½½ã
é¤äºè¿ä¸ç§ç±»å è½½å¨ä¹å¤ï¼ç¨æ·è¿å¯ä»¥å å
¥èªå®ä¹çç±»å è½½å¨æ¥è¿è¡æå±ï¼ä»¥æ»¡è¶³èªå·±çç¹æ®éæ±ãå°±æ¯å¦è¯´ï¼æä»¬å¯ä»¥å¯¹ Java ç±»çåèç ï¼ `.class` æä»¶ï¼è¿è¡å å¯ï¼å è½½æ¶åå©ç¨èªå®ä¹çç±»å è½½å¨å¯¹å
¶è§£å¯ã

é¤äº `BootstrapClassLoader` æ¯ JVM èªèº«çä¸é¨åä¹å¤ï¼å
¶ä»ææçç±»å è½½å¨é½æ¯å¨ JVM å¤é¨å®ç°çï¼å¹¶ä¸å
¨é½ç»§æ¿èª `ClassLoader`æ½è±¡ç±»ãè¿æ ·åç好夿¯ç¨æ·å¯ä»¥èªå®ä¹ç±»å è½½å¨ï¼ä»¥ä¾¿è®©åºç¨ç¨åºèªå·±å³å®å¦ä½å»è·åæéçç±»ã
æ¯ä¸ª `ClassLoader` å¯ä»¥éè¿`getParent()`è·åå
¶ç¶ `ClassLoader`ï¼å¦æè·åå° `ClassLoader` 为`null`çè¯ï¼é£ä¹è¯¥ç±»æ¯éè¿ `BootstrapClassLoader` å è½½çã
```java
public abstract class ClassLoader {
...
// ç¶å è½½å¨
private final ClassLoader parent;
@CallerSensitive
public final ClassLoader getParent() {
//...
}
...
}
```
**为ä»ä¹ è·åå° `ClassLoader` 为`null`å°±æ¯ `BootstrapClassLoader` å è½½çå¢ï¼** è¿æ¯å 为`BootstrapClassLoader` ç± C++ å®ç°ï¼ç±äºè¿ä¸ª C++ å®ç°çç±»å è½½å¨å¨ Java 䏿¯æ²¡æä¸ä¹å¯¹åºçç±»çï¼æä»¥æ¿å°çç»ææ¯ nullã
ä¸é¢æä»¬æ¥çä¸ä¸ªè·å `ClassLoader` çå°æ¡ä¾ï¼
```java
public class PrintClassLoaderTree {
public static void main(String[] args) {
ClassLoader classLoader = PrintClassLoaderTree.class.getClassLoader();
StringBuilder split = new StringBuilder("|--");
boolean needContinue = true;
while (needContinue){
System.out.println(split.toString() + classLoader);
if(classLoader == null){
needContinue = false;
}else{
classLoader = classLoader.getParent();
split.insert(0, "\t");
}
}
}
}
```
è¾åºç»æ(JDK 8 )ï¼
```
|--sun.misc.Launcher$AppClassLoader@18b4aac2
|--sun.misc.Launcher$ExtClassLoader@53bd815b
|--null
```
ä»è¾åºç»æå¯ä»¥çåºï¼
- æä»¬ç¼åç Java ç±» `PrintClassLoaderTree` ç `ClassLoader` æ¯`AppClassLoader`ï¼
- `AppClassLoader`çç¶ `ClassLoader` æ¯`ExtClassLoader`ï¼
- `ExtClassLoader`çç¶`ClassLoader`æ¯`Bootstrap ClassLoader`ï¼å æ¤è¾åºç»æä¸º nullã
### èªå®ä¹ç±»å è½½å¨
æä»¬åé¢ä¹è¯´è¯´äºï¼é¤äº `BootstrapClassLoader` å
¶ä»ç±»å è½½å¨åç± Java å®ç°ä¸å
¨é¨ç»§æ¿èª`java.lang.ClassLoader`ã妿æä»¬è¦èªå®ä¹èªå·±çç±»å è½½å¨ï¼å¾ææ¾éè¦ç»§æ¿ `ClassLoader`æ½è±¡ç±»ã
`ClassLoader` ç±»æä¸¤ä¸ªå
³é®çæ¹æ³ï¼
- `protected Class loadClass(String name, boolean resolve)`ï¼å è½½æå®äºè¿å¶åç§°çç±»ï¼å®ç°äºåäº²å§æ´¾æºå¶ ã`name` 为类çäºè¿å¶åç§°ï¼`resove` å¦æä¸º trueï¼å¨å è½½æ¶è°ç¨ `resolveClass(Class> c)` æ¹æ³è§£æè¯¥ç±»ã
- `protected Class findClass(String name)`ï¼æ ¹æ®ç±»çäºè¿å¶åç§°æ¥æ¥æ¾ç±»ï¼é»è®¤å®ç°æ¯ç©ºæ¹æ³ã
宿¹ API ææ¡£ä¸åå°ï¼
> Subclasses of `ClassLoader` are encouraged to override `findClass(String name)`, rather than this method.
>
> 建议 `ClassLoader`çåç±»éå `findClass(String name)`æ¹æ³è䏿¯`loadClass(String name, boolean resolve)` æ¹æ³ã
妿æä»¬ä¸æ³æç ´åäº²å§æ´¾æ¨¡åï¼å°±éå `ClassLoader` ç±»ä¸ç `findClass()` æ¹æ³å³å¯ï¼æ æ³è¢«ç¶ç±»å è½½å¨å è½½çç±»æç»ä¼éè¿è¿ä¸ªæ¹æ³è¢«å è½½ã使¯ï¼å¦ææ³æç ´åäº²å§æ´¾æ¨¡ååéè¦éå `loadClass()` æ¹æ³ã
## åäº²å§æ´¾æ¨¡å
### åäº²å§æ´¾æ¨¡åä»ç»
ç±»å è½½å¨æå¾å¤ç§ï¼å½æä»¬æ³è¦å è½½ä¸ä¸ªç±»çæ¶åï¼å
·ä½æ¯åªä¸ªç±»å è½½å¨å è½½å¢ï¼è¿å°±éè¦æå°åäº²å§æ´¾æ¨¡åäºã
æ ¹æ®å®ç½ä»ç»ï¼
> The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. The virtual machine's built-in class loader, called the "bootstrap class loader", does not itself have a parent but may serve as the parent of a ClassLoader instance.
ç¿»è¯è¿æ¥å¤§æ¦çæææ¯ï¼
> `ClassLoader` 类使ç¨å§ææ¨¡åæ¥æç´¢ç±»åèµæºãæ¯ä¸ª `ClassLoader` å®ä¾é½æä¸ä¸ªç¸å
³çç¶ç±»å è½½å¨ãéè¦æ¥æ¾ç±»æèµæºæ¶ï¼`ClassLoader` å®ä¾ä¼å¨è¯å¾äº²èªæ¥æ¾ç±»æèµæºä¹åï¼å°æç´¢ç±»æèµæºçä»»å¡å§æç»å
¶ç¶ç±»å è½½å¨ã
> èææºä¸è¢«ç§°ä¸º "bootstrap class loader"çå
置类å è½½å¨æ¬èº«æ²¡æç¶ç±»å è½½å¨ï¼ä½æ¯å¯ä»¥ä½ä¸º `ClassLoader` å®ä¾çç¶ç±»å è½½å¨ã
ä»ä¸é¢çä»ç»å¯ä»¥çåºï¼
- `ClassLoader` 类使ç¨å§ææ¨¡åæ¥æç´¢ç±»åèµæºã
- åäº²å§æ´¾æ¨¡åè¦æ±é¤äºé¡¶å±çå¯å¨ç±»å è½½å¨å¤ï¼å
¶ä½çç±»å è½½å¨é½åºæèªå·±çç¶ç±»å è½½å¨ã
- `ClassLoader` å®ä¾ä¼å¨è¯å¾äº²èªæ¥æ¾ç±»æèµæºä¹åï¼å°æç´¢ç±»æèµæºçä»»å¡å§æç»å
¶ç¶ç±»å è½½å¨ã
ä¸å¾å±ç¤ºçåç§ç±»å è½½å¨ä¹é´ç屿¬¡å
³ç³»è¢«ç§°ä¸ºç±»å è½½å¨çâ**åäº²å§æ´¾æ¨¡å(Parents Delegation Model)**âã

注æ â ï¸ï¼åäº²å§æ´¾æ¨¡å并䏿¯ä¸ç§å¼ºå¶æ§ç约æï¼åªæ¯ JDK 宿¹æ¨èçä¸ç§æ¹å¼ã妿æä»¬å 为æäºç¹æ®éæ±æ³è¦æç ´åäº²å§æ´¾æ¨¡åï¼ä¹æ¯å¯ä»¥çï¼åæä¼ä»ç»å
·ä½çæ¹æ³ã
å
¶å®è¿ä¸ªå亲翻è¯ç容æè®©å«äººè¯¯è§£ï¼æä»¬ä¸è¬çè§£çåäº²é½æ¯ç¶æ¯ï¼è¿éçå亲æ´å¤å°è¡¨è¾¾çæ¯âç¶æ¯è¿ä¸è¾âç人èå·²ï¼å¹¶ä¸æ¯è¯´ççæä¸ä¸ª `MotherClassLoader` åä¸ä¸ª`FatherClassLoader` ã个人è§å¾ç¿»è¯æåäº²å§æ´¾æ¨¡åæ´å¥½ä¸äºï¼ä¸è¿ï¼å½å
æ¢ç¶ç¿»è¯æäºåäº²å§æ´¾æ¨¡åå¹¶æµä¼ äºï¼æç
§è¿ä¸ªæ¥ä¹æ²¡é®é¢ï¼ä¸è¦è¢«è¯¯è§£äºå°±å¥½ã
å¦å¤ï¼ç±»å è½½å¨ä¹é´çç¶åå
³ç³»ä¸è¬ä¸æ¯ä»¥ç»§æ¿çå
³ç³»æ¥å®ç°çï¼èæ¯é常使ç¨ç»åå
³ç³»æ¥å¤ç¨ç¶å è½½å¨ç代ç ã
```java
public abstract class ClassLoader {
...
// ç»å
private final ClassLoader parent;
protected ClassLoader(ClassLoader parent) {
this(checkCreateClassLoader(), parent);
}
...
}
```
å¨é¢å对象ç¼ç¨ä¸ï¼æä¸æ¡é常ç»å
¸ç设计ååï¼**ç»åä¼äºç»§æ¿ï¼å¤ç¨ç»åå°ç¨ç»§æ¿ã**
### åäº²å§æ´¾æ¨¡åçæ§è¡æµç¨
åäº²å§æ´¾æ¨¡åçå®ç°ä»£ç é常ç®åï¼é»è¾é常æ¸
æ°ï¼é½éä¸å¨ `java.lang.ClassLoader` ç `loadClass()` ä¸ï¼ç¸å
³ä»£ç å¦ä¸æç¤ºã
```java
protected Class> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
//é¦å
ï¼æ£æ¥è¯¥ç±»æ¯å¦å·²ç»å è½½è¿
Class c = findLoadedClass(name);
if (c == null) {
//妿 c 为 nullï¼å说æè¯¥ç±»æ²¡æè¢«å è½½è¿
long t0 = System.nanoTime();
try {
if (parent != null) {
//å½ç¶ç±»çå è½½å¨ä¸ä¸ºç©ºï¼åéè¿ç¶ç±»çloadClassæ¥å 载该类
c = parent.loadClass(name, false);
} else {
//å½ç¶ç±»çå è½½å¨ä¸ºç©ºï¼åè°ç¨å¯å¨ç±»å è½½å¨æ¥å 载该类
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
//é空ç¶ç±»çç±»å è½½å¨æ æ³æ¾å°ç¸åºçç±»ï¼åæåºå¼å¸¸
}
if (c == null) {
//å½ç¶ç±»å è½½å¨æ æ³å è½½æ¶ï¼åè°ç¨findClassæ¹æ³æ¥å 载该类
//ç¨æ·å¯éè¿è¦åè¯¥æ¹æ³ï¼æ¥èªå®ä¹ç±»å è½½å¨
long t1 = System.nanoTime();
c = findClass(name);
//ç¨äºç»è®¡ç±»å è½½å¨ç¸å
³çä¿¡æ¯
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
//对类è¿è¡linkæä½
resolveClass(c);
}
return c;
}
}
```
æ¯å½ä¸ä¸ªç±»å è½½å¨æ¥æ¶å°å è½½è¯·æ±æ¶ï¼å®ä¼å
å°è¯·æ±è½¬åç»ç¶ç±»å è½½å¨ãå¨ç¶ç±»å è½½å¨æ²¡ææ¾å°æè¯·æ±çç±»çæ
åµä¸ï¼è¯¥ç±»å è½½å¨æä¼å°è¯å»å è½½ã
ç»åä¸é¢çæºç ï¼ç®åæ»ç»ä¸ä¸åäº²å§æ´¾æ¨¡åçæ§è¡æµç¨ï¼
- å¨ç±»å è½½çæ¶åï¼ç³»ç»ä¼é¦å
夿å½åç±»æ¯å¦è¢«å è½½è¿ãå·²ç»è¢«å è½½çç±»ä¼ç´æ¥è¿åï¼å¦åæä¼å°è¯å è½½ï¼æ¯ä¸ªç¶ç±»å è½½å¨é½ä¼èµ°ä¸éè¿ä¸ªæµç¨ï¼ã
- ç±»å è½½å¨å¨è¿è¡ç±»å è½½çæ¶åï¼å®é¦å
ä¸ä¼èªå·±å»å°è¯å è½½è¿ä¸ªç±»ï¼èæ¯æè¿ä¸ªè¯·æ±å§æ´¾ç»ç¶ç±»å è½½å¨å»å®æï¼è°ç¨ç¶å è½½å¨ `loadClass()`æ¹æ³æ¥å 载类ï¼ãè¿æ ·çè¯ï¼ææçè¯·æ±æç»é½ä¼ä¼ éå°é¡¶å±çå¯å¨ç±»å è½½å¨ `BootstrapClassLoader` ä¸ã
- åªæå½ç¶å è½½å¨åé¦èªå·±æ æ³å®æè¿ä¸ªå 载请æ±ï¼å®çæç´¢èå´ä¸æ²¡ææ¾å°æéçç±»ï¼æ¶ï¼åå è½½å¨æä¼å°è¯èªå·±å»å è½½ï¼è°ç¨èªå·±ç `findClass()` æ¹æ³æ¥å 载类ï¼ã
ð æå±ä¸ä¸ï¼
**JVM å¤å®ä¸¤ä¸ª Java ç±»æ¯å¦ç¸åçå
·ä½è§å**ï¼JVM ä¸ä»
è¦çç±»çå
¨åæ¯å¦ç¸åï¼è¿è¦çå è½½æ¤ç±»çç±»å è½½å¨æ¯å¦ä¸æ ·ãåªæä¸¤è
é½ç¸åçæ
åµï¼æè®¤ä¸ºä¸¤ä¸ªç±»æ¯ç¸åçãå³ä½¿ä¸¤ä¸ªç±»æ¥æºäºåä¸ä¸ª `Class` æä»¶ï¼è¢«åä¸ä¸ªèææºå è½½ï¼åªè¦å è½½å®ä»¬çç±»å è½½å¨ä¸åï¼é£è¿ä¸¤ä¸ªç±»å°±å¿
å®ä¸ç¸åã
### åäº²å§æ´¾æ¨¡åç好å¤
åäº²å§æ´¾æ¨¡åä¿è¯äº Java ç¨åºç稳å®è¿è¡ï¼å¯ä»¥é¿å
ç±»çéå¤å è½½ï¼JVM åºåä¸åç±»çæ¹å¼ä¸ä»
ä»
æ ¹æ®ç±»åï¼ç¸åçç±»æä»¶è¢«ä¸åçç±»å è½½å¨å 载产ççæ¯ä¸¤ä¸ªä¸åçç±»ï¼ï¼ä¹ä¿è¯äº Java çæ ¸å¿ API ä¸è¢«ç¯¡æ¹ã
å¦ææ²¡æä½¿ç¨åäº²å§æ´¾æ¨¡åï¼èæ¯æ¯ä¸ªç±»å è½½å¨å è½½èªå·±çè¯å°±ä¼åºç°ä¸äºé®é¢ï¼æ¯å¦æä»¬ç¼åä¸ä¸ªç§°ä¸º `java.lang.Object` ç±»çè¯ï¼é£ä¹ç¨åºè¿è¡çæ¶åï¼ç³»ç»å°±ä¼åºç°ä¸¤ä¸ªä¸åç `Object` ç±»ãåäº²å§æ´¾æ¨¡åå¯ä»¥ä¿è¯å è½½çæ¯ JRE éçé£ä¸ª `Object` ç±»ï¼è䏿¯ä½ åç `Object` ç±»ãè¿æ¯å 为 `AppClassLoader` å¨å è½½ä½ ç `Object` ç±»æ¶ï¼ä¼å§æç» `ExtClassLoader` å»å è½½ï¼è `ExtClassLoader` åä¼å§æç» `BootstrapClassLoader`ï¼`BootstrapClassLoader` åç°èªå·±å·²ç»å è½½è¿äº `Object` ç±»ï¼ä¼ç´æ¥è¿åï¼ä¸ä¼å»å è½½ä½ åç `Object` ç±»ã
### æç ´åäº²å§æ´¾æ¨¡åæ¹æ³
~~为äºé¿å
åäº²å§ææºå¶ï¼æä»¬å¯ä»¥èªå·±å®ä¹ä¸ä¸ªç±»å è½½å¨ï¼ç¶åéå `loadClass()` å³å¯ã~~
**ð ä¿®æ£ï¼åè§ï¼[issue871](https://github.com/Snailclimb/JavaGuide/issues/871) ï¼**ï¼èªå®ä¹å è½½å¨çè¯ï¼éè¦ç»§æ¿ `ClassLoader` ã妿æä»¬ä¸æ³æç ´åäº²å§æ´¾æ¨¡åï¼å°±éå `ClassLoader` ç±»ä¸ç `findClass()` æ¹æ³å³å¯ï¼æ æ³è¢«ç¶ç±»å è½½å¨å è½½çç±»æç»ä¼éè¿è¿ä¸ªæ¹æ³è¢«å è½½ã使¯ï¼å¦ææ³æç ´åäº²å§æ´¾æ¨¡ååéè¦éå `loadClass()` æ¹æ³ã
为ä»ä¹æ¯éå `loadClass()` æ¹æ³æç ´åäº²å§æ´¾æ¨¡åå¢ï¼åäº²å§æ´¾æ¨¡åçæ§è¡æµç¨å·²ç»è§£éäºï¼
> ç±»å è½½å¨å¨è¿è¡ç±»å è½½çæ¶åï¼å®é¦å
ä¸ä¼èªå·±å»å°è¯å è½½è¿ä¸ªç±»ï¼èæ¯æè¿ä¸ªè¯·æ±å§æ´¾ç»ç¶ç±»å è½½å¨å»å®æï¼è°ç¨ç¶å è½½å¨ `loadClass()`æ¹æ³æ¥å 载类ï¼ã
æä»¬æ¯è¾çæç Tomcat æå¡å¨ä¸ºäºè½å¤ä¼å
å è½½ Web åºç¨ç®å½ä¸çç±»ï¼ç¶ååå è½½å
¶ä»ç®å½ä¸çç±»ï¼å°±èªå®ä¹äºç±»å è½½å¨ `WebAppClassLoader` æ¥æç ´åäº²å§ææºå¶ãè¿ä¹æ¯ Tomcat ä¸ Web åºç¨ä¹é´çç±»å®ç°é离çå
·ä½åçã
Tomcat çç±»å è½½å¨ç屿¬¡ç»æå¦ä¸ï¼

æå
´è¶£çå°ä¼ä¼´å¯ä»¥èªè¡ç ç©¶ä¸ä¸ Tomcat ç±»å è½½å¨ç屿¬¡ç»æï¼è¿æå©äºæä»¬ææ Tomcat é离 Web åºç¨çåçï¼æ¨èèµææ¯[ãæ·±å
¥æè§£ Tomcat & Jettyã](http://gk.link/a/10Egr)ã
## æ¨èé
读
- ãæ·±å
¥æè§£ Java èææºã
- æ·±å
¥åæ Java ClassLoader åçï¼https://blog.csdn.net/xyang81/article/details/7292380
- Java ç±»å è½½å¨(ClassLoader)ï¼http://gityuan.com/2016/01/24/java-classloader/
- Class Loaders in Javaï¼https://www.baeldung.com/java-classloaders
- Class ClassLoader - Oracle 宿¹ææ¡£ï¼https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html
- è大é¾ç Java ClassLoader åä¸ç解就èäºï¼https://zhuanlan.zhihu.com/p/51374915