类加载器的作用:将.class文件的字节码文件加载到java虚拟机中,在堆中生成java.lang.class对象(模板对象,一个类只有一个模板对象)将静态变量转换成方法区运行时数据结构。
类缓存:当一个class文件被一个类加载器加载后,它会缓存一段时间,当class文件被加载时会先去查缓存,如果缓存有就不加载了
Register r = new Register();//可以拆解成 Register r;r = new Register()
//Register r;是对象的引用此时r的指向是null,存放在java栈里,
new Register()会生成一个具体的对象在堆里r的指向是具体实例
Class<Register> r1= Register.class;
Class<Register> r2= Register.class;
System.out.println(r1);
System.out.println(r2);
//r1与r2与r.getClass()一样
类加载器的分类:
第一级:bootclassloader 顶级类加载器 c++语言编写没有父类
第二级:extclassloader 扩展类加载器 他有个parent属性 bootclassloader(类加载器不存在继承关系,只是通过parent属性模拟父子关系)getparent是null(当值为null时 有两种可能性 1.extclassloader 没有父级 2.java获取不到 这里因为extclassloader的父级是 bootclassloader他是由c++编写的)
第三级:appclassloader:应用加载器他有个parent属性 extclassloader
第四级:自定义类加载器
类加载器是通过双亲委派机制来工作的,
什么是双亲委派机制?
当一个class文件被加载的时候不考虑我们自定义的类加载器,首先会在appclassloader里检查看有没有缓存过,有缓存直接使用,没有缓存则看appclassloader的父类加载器 extclassloader里有没有缓存,没有缓存则看extclassloader的父类 bootclassloader是否有缓存,如果没有缓存则因为bootclassloader没有父类了,则看bootclassloader是否有这个类,有则加载没有就往下一直找。
这就是双亲委派机制
双亲委派机制的目的:安全性,保证java核心api不会被篡改,举一个例子,我们创建了一个java.lang.string类,java的jar包里也有这个类,当我们创建string对象时 生成的是java的jar包的java.lang.string类。
避免类的重复加载,每次都从下往上查一遍,如果父类加载器加载过,子类加载器不再加载