类加载器的种类(主要)

启动类加载器(Bootstrap ClassLoader):负责加载JRE核心类库,像JRE中的rt.jar等(C/C++);
扩展类加载器(Extension ClassLoader):负责加载JRE扩展目录ext中的jar包;
系统类加载器(Application ClassLoader):负责加载ClassPath路径下的类包;
2.类加载子系统 - 图1
类加载器子系统作用
类加载器系统负责从文件系统或者网络中加载class文件,class文件开头有特定的文件标识。

加载: 通过一个类的全限定名获取此类的二进制字节流
将这个字节流锁代表的静态存储结构转化为方法区的运行时数据结构
在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问接口。

JVM支持两种类型的类加载器,分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)
Java虚拟机将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器

为什么要自定义类加载器:
隔离加载类
修改类加载的方式
扩展加载源
防止源码泄露

实现步骤
1.开发人员可以通过继承ClassLoader类的方式,实现自己的类加载器
2.在JDK1.2之前,在自定义类加载器时,总会去继承ClassLoader类并重写loadClass()方法,从而实现自定义的类加载类,但是1.2过后已经不建议用户去覆盖loadClass方法,而是把自定义类加载逻辑写在findClass方法中。
3.在编写自定义类加载器时,如果没有太过复杂的需求,可以直接继承URLClassLoader类,这样就不用自己去编写findClass方法以及其获取字节码流的方式,使自定义类加载编写更加简洁。

双亲委派机制:
image.png
Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存中生成class对象。而且加载某个类class文件时,Java虚拟机采用的是双亲委派模型,即把请求交由父类处理,它是一种任务委派模式。

工作原理
1.如果一个类加载器收到了类加载的请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行
2.如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器。
3.如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。

双亲委派机制的优点:
避免重复加载
保护程序安全,避免源码被篡改
沙箱安全机制:
自定义String类,但是在加载自定义Stirng类的时候回率先使用引导类加载器加载,而引导类加载器在加载过程中会先加载jdk自带的文件,报错说没有main方法,就是因为加载的是官方的String类,这样可以保证对java核心源代码的保护,这就是沙箱安全机制。

  1. public class String {
  2. public static void main(String[] args) {
  3. }
  4. }
  5. //无法运行,报错没有main方法

在JVM中表示两个class对象是否为同一个类存在的两个必要条件
类的完整名必须一致,包括类名
加载类的ClassLoader(指ClassLoader实例对象)必须相同