理解ClassLoader双亲委托模型关键

看图

理解ClassLoader双亲委托模型关键_第1张图片

  1. Bootstrap classLoader:采用native code实现,是JVM的一部分,主要加载JVM自身工作需要的类,如java.lang.*、java.uti.*等; 这些类位于$JAVA_HOME/jre/lib/rt.jar。Bootstrap ClassLoader不继承自ClassLoader,因为它不是一个普通的Java类,底层由C++编写,已嵌入到了JVM内核当中,当JVM启动后,Bootstrap ClassLoader也随着启动,负责加载完核心类库后,并构造Extension ClassLoader和App ClassLoader类加载器。
  2. ExtClassLoader:扩展的class loader,加载位于$JAVA_HOME/jre/lib/ext目录下的扩展jar。
  3. AppClassLoader:当前应用class loader,parent属性引用的是ExtClassLoader,加载$CLASSPATH下的目录和jar;它负责加载应用程序主函数类。
  4. 自定义类加载器:需要extends ClassLoader,parent是当前应用类加载器(AppClassLoader)

关键1

在一个自定义的classloader  A接收到加载类的指令时

首先查看缓存里有没有,没有的话就交给其父亲(parent)B(AppClassLoader classloader)去加载,

如果B没有找到对应的类则会交给C(Extension classloader)去加载;

同理 父亲C接到这个指令时也会先检查缓存里是否已经加载了,如果缓存中没有就去叫它的父亲D(Bootstrap classloader)去找

 

D说:我给你看一下%JAVA_HOME%/lib下有这个类没,因为我只能到这个目录下去找哦 亲;

D如果没有找到,然后就对C说:“我并没有找到,你还是自己去找吧,我只能帮你到这里了”;

 

然后C说我到%JAVA_HOME%/lib/ext下去给你找找,因为我只能访问这个目录;

C如果没有找到,然后就对B说:“我并没有找到,你还是自己去找吧,我只能帮你到这里了”;

 

然后B到应用的-classpath目录下的jar包去找对应的文件,因为它默认访问这个目录(一般是工程的lib目录)

如果B在应用的classpath目录下还是没有找到该类,于是就对A说:“你要找的文件是不是在你自定义的路径下哦?你还是自己去找吧”

 

A说:“我靠 找到了,果然在我自定义的D盘里的一个jar包里面“

 

这就是完整的加载类过程;

之前我理解的所有的类都是 bootstarp classloader加载的,这个说法是错的。

关键2

虚拟机判断两个类是否相同类依据:1、全类名是否一致   2、是否由相同类加载器

所以单例模式设计要注意这点

 

关键3

JAVA虚拟机不是一下子加载所有工程里的class文件的,而是需要时才会加载,比如 一个类里引用了某个类,或者用了new关键字等

 

附:

JAVA虚拟机加载class文件步骤

1、装载:查找和导入Class文件 ,生成对应的Class 对象

2、链接:其中解析步骤是可以选择的 

 (a)检查:检查载入的class文件数据的正确性

 (b)准备:给类的静态变量分配存储空间 

 (c)解析:将符号引用转成直接引用 

3、初始化:对静态变量,静态代码块执行初始化工作

 

 

你可能感兴趣的:(classloader,JAVA)