1、类的加载过程
类加载器
首先,在Java中有三个类加载器,分别是Bootstrploader(引导类加载器),ExtClassLoader(扩展类加载器) , AppClassLoader(应用类加载器)。
其中Bootstrploader是最底层的类加载器,它是用C语言来实现的,它主要用来加载jre和jre路径。ExtClassLoader则使用Java语言编写用来加载jre下系统类库。 AppClassLoader用来加载自己写的类。
类的加载过程
加载——链接——初始化
加载:用类加载器在指定的路径上加载对应的class文件(加载class对象 类的所有信息);
链接:(准备,验正,引用)验证上面的字节码文件是否能够在当前的jvm上运行;给静态成员开辟内存;它如果有基类,重复上面的步骤加载基类;
初始化:给static静态成员进行初始化工作;
2、双亲委托模型
当我们了解了基本的类的加载过程,我们就可以开始了解双亲委托模型了。
public Class<?> loadClass(String name) throws ClassNotFoundException 【委托方法实现函数】
双亲委托过程:
1、当前ClassLoader从自己已加载的类中查询是否此类已经加载,如果已加载则直接返回原来已加载的类。(每个类加载器都有自己的加载缓存,当类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回)
2、当前的类加载器如果没有找到加载类的时候会委托自己的父类去找,一直向上,直到 Bootstrploader
3、找到最后都没有的时候,就自己加载缓存,方便下次再找。
为什么要用双亲委托?:
因为类加载器的命名空间。它是指要确定某一个类,需要类的全限定名以及加载此类的ClassLoader来共同确定;
打破双亲委托的情况:
Java中有一个SPI(Service Provider Interface)标准,使用了SPI的库,比如JDBC,JNDI等,
我们都知道JDBC需要第三方提供的驱动才可以;而JDBC的API一部分已经被Bootstrploader加载,
所以Java提出了线程上下文类加载概念,线程类加载器默认会从父线程继承,如果没有指定的话,
默认就是系统类加载器(AppClassLoader)