38 ClassLoader类加载器双亲委派机制

1,简单回顾Class 字节码生成的原理
2,哪些操作会触发类加载器
3,什么是类加载器,类加载器的作用
4,类加载器的加载类型有哪些来源
5,为什么来加载器中双亲委派机制原理
6,双亲委派机制有哪些优点

7,自己定义一个java.lang.object会与rt包冲突吗
不冲突也不报错
8,如何打破双亲委派机制 spi机制
9,手写定义一个类加载器
10 tomact如何打破双亲委派机制

image.png

.java源代码---》.class字节码---》》JVm 虚拟机 (从软件方面屏蔽硬件,指令层面细节实现跨平台)----》1,windows机器码 2,Linux机器码。

什么是类加载器:
将我们的class 文件读取到内存中

读取class 文件来源有哪些?
1,自己写的java源代码 编译成class文件 硬盘读取
2, 通过网络的方式下载class文件
3,war,jar 解压后都是class文件
4.从专门的数据库中读取的class文件
5.使用java cglib、动态代理生成的代理类class文件


image.png

验证: 验证阶段用于检验被加载的类是否有正确的内部结构,并和其他类协调一致。java是相对C++语言是安全的语言,例如他有C++不具有的数组越界检查。这本身就是对自身安全的一种保护,验证阶段是java 非常重要的一个阶段,他会直接的保证应用是否会被 恶意入侵的一种重要的防线,越是严谨的验证机制越安全。验证的目的在于确保Class文件的字节流中包含信息符合当前虚拟机要求,不会危害虚拟机自身的安全。其主要有4中验证,文件格式验证,元数据验证,字节码验证,符号引用验证。
四种验证做进一步验证:
1,文件格式验证: 主要验证字节流是否符合class文件格式规范。并且能被当前的虚拟机加载处理。例如: 主 ,次版本号是否在当前虚拟机处理的范围内,常量池中是否有不被支持的常量类型。指向常量的中的索引值是否存在不存在常量或不符合类型的常量。
2,元数据验证: 对字节码描述的信息进行语义的分析,分析是否符合java的语言语法的规范。
3,字节码验证, 最重要的验证环节,分析数据流和控制,确定语义是否合法的,符合逻辑的。主要的针对元数据验证后对方法体的验证。保证类方法在运行时不会有危害出现。
4, 符号引用验证: 主要针对符号引用转换为直接引用的时候,是会延伸到第三解析阶段,主要是去确定访问类型等涉及到引用的情况。主要是要保证引用一定会被访问到,不会出现类无法访问的情况。
准备:
准备阶段负责为类的静态变量分配内存,并设置默认初始值。
解析:
将类的二进制数据中的符号引用替换成直接引用。说明下: 符号引用: 符号引用是以一组符号来描述所引用的目标,符号可以是任何的字面形式的字面量,只要不会出现冲突能够定位到就行,布局和内存无关。直接引用: 指向目标的指针,偏移量或者能够直接定位的句柄,该引用是和内存中的布局有关,并且一定加载过来的
初始化:
初始化该类:

类加载器的分类:
1,启动(Bootstrap)类加载器: 记载jvm 自身工作需要的类,他又jvm自己实现,他会加载JAVA_HOME/jre/lib下的文件 底层是C语言实现;获取classloader是null 2,扩展(Extension)类加载器:他是JVM的一部分,由sun.miscLanucherExtClassLoader实现。他会加载EXtClassLoader 实现,会加载JAVA_HOME/jre/lib/ext 目录中的文件(或由System.getProperty(ClasssLoader实现。他加载我们工程目录classpath下的class和jar,底层是java实现
4,自定义类加载器: 也就是用户自己定义的类加载器。

image.png

ClassLoader 类加载器的分类

1,启动类加载器
2,扩展类加载器
3,应用类加载器
4,自定义加载器

类加载器


image.png
image.png

package com.taotao.jvm1.classloader;

import java.util.Arrays;
import java.util.List;

/**
 *@author tom
 *Date  2020/8/6 0006 9:53
 *
 */
public class Test003 {
    public static void main(String[] args) {
         //   bootstrapClassLoader();
       // extClassLoader();
        appClassLoader();

    }

    //启动类加载器
    private static void bootstrapClassLoader() {
        String property=System.getProperty("sun.boot.class.path");
        List list= Arrays.asList(property.split(";"));
        list.forEach((t)->{
            System.out.println("启动类加载器目录:"+t);
        });


    }


    //扩展类加载器
    public  static  void extClassLoader(){
        String property=System.getProperty("java.ext.dirs");
        List list=Arrays.asList(property.split(";"));
        list.forEach((t)->{
            System.out.println("扩展类加载器"+t);
        });
    }
    //类加载器
    public  static  void appClassLoader(){
        String property=System.getProperty("java.class.path");
        List list=Arrays.asList(property.split(";"));
        list.forEach((t)->{
            System.out.println("应用类加载器"+t);
        });
    }
}


注意: 每个类加载器都有自己不同的职责;读取class文件范围:

image.png

ClassLoader 类加载器双亲委派机制:
ClassLoader:有四种类: 每个类加载器都有层次关系
当我们类加载器收到一个请求的时候,首先会依次向上查找最顶层没有父类的类类加载器 (启动类加载器),依次向下读取class文件,如果该类加载器已经读取到class文件的时候,不在向下读取。

image.png

双亲委派机制的好处:
以上向下查找最顶端启动类加载器读取class文件,只要启动类加载器读取成功后,不在向下扩展,应用类加载器读取。

好处: 防御开发者定义包名和类名 与java 虚拟机定义完全一样,防止冲突,保证该类在内存中只有一个

双亲委派机制原则
为什么java虚拟机会设置多个不同的类加载器

启动类加载器
扩展类加载器

那些操作会初始化类加载器
类的主动使用:
1.调用类的静态方法
2.invokeStatic 调用静态方法
3.Main
4.New
5.Class.formname
6.子类初始化一定会初始化父类
初始化一个类,那么一定会触发类加载器

image.png

类加载器的双亲委派机制

首先在我们类加载器分为四种 自定义类加载器、应用类加载器、扩展类加载器、启动类加载器。

当一个类加载器收到请求之后,首先会依次向上查找到最顶层类加载器(启动类加载器),依次向下加载class文件,如果已经加载到class文件,子加载器不会加继续加载该class文件。

[图片上传失败...(image-fd6d00-1596848757197)]

双亲委派机制机制的好处

目的就是为了防御开发者为定义的类与jdk定义源码类产生冲突问题,保证该类在内存中的唯一性。

image.png

你可能感兴趣的:(38 ClassLoader类加载器双亲委派机制)