1:定义:类加载机制指虚拟机把描述类的数据从.class文件加载到内存;
它的整个生命周期包括:加载—验证—准备—解析—初始化—使用—卸载七个阶段;
2:类加载器分类:
启动类加载器,拓展类加载器,应用类加载器;(加载顺序从左到右)
3:类加载的三种方式:
(1)程序启动时,通过main()方法进行加载;
(2)通过Class.forName()方法动态加载,会默认执行初始化块(static{}),但是Class.forName(name,initialize,loader)中的initialze可指定是否要执行初始化块。
(3)通过ClassLoader.loadClass()方法动态加载,不会执行初始化块。
4:双亲委派原则:
当一个类加载器收到类加载任务时,会先交给其父类加载器去执行,因此所有的加载任务最终都会传递给顶层的启动类加载器。只有当父类无法完成加载任务时,才会让子类尝试执行加载任务。
好处:
可以避免重复加载,父类已经加载了,子类就不需要再加载了;
更加安全,每个加载器只能加载自己能力范围内的类;
5:双亲委派原则的缺陷:
父类加载器无法加载子类加载器路径中的类,比如数据库中的spi服务(一种服务发现机制,用来自动加载指定路径下的类),classloader是启动类加载器,但是加载的jdbc.driver必须用应用类加载器加载,这就导致双亲委派原则无法使用;
6:打破双亲委派原则
这时候需要打破双亲委派原则,针对上述问题,如果我们能在启动类加载器中调用应用类加载器进行加载,就可以解决spi服务的问题,这时候需要使用到的就是线程上下文加载器;线程上下文加载器让父类加载器可以调用子类加载器进行加载;
另一种方法是自定义加载器,重写loadclass方法,重写这个方法可以自定义使用什么样的加载器,也可以自定义加载委派机制,也就等价于打破了双亲委派模型;