ClassLoader的分类有哪些?加载顺序是什么?类加载的顺序又是什么?
答:ClassLoader分为4种:Jvm类加载器(BootstarpClassLoader),Jvm扩展类加载器(extClassLoader),系统类加载器(SystemClassLoader),自定义类加载器(AppClassLoader)
JVM预定义有三种类加载器,当一个 JVM启动的时候,Java开始使用如下三种类加载器:
1)根类加载器(bootstrap class loader):这个类加载器负责将lib目录下的类库加载到虚拟机内存中,用来加载java的核心库,此类加载器并不继承于java.lang.ClassLoader,不能被java程序直接调用,代码是使用C++编写的.是虚拟机自身的一部分。
2)扩展类加载器(extensions class loader):它负责加载JRE的扩展目录,lib/ext或者由java.ext.dirs系统属性指定的目录中的JAR包的类。由Java语言实现,父类加载器为null。
3)系统类加载器(system class loader):被称为系统(也称为应用)类加载器,它负责在JVM启动时加载来自Java命令的-classpath选项、java.class.path系统属性,或者CLASSPATH换将变量所指定的JAR包和类路径。程序可以通过ClassLoader的静态方法getSystemClassLoader()来获取系统类加载器。如果没有特别指定,则用户自定义的类加载器都以此类加载器作为父加载器。由Java语言实现,父类加载器为ExtClassLoader。
类加载器加载Class大致要经过如下8个步骤:
1检测此Class是否载入过,即在缓冲区中是否有此Class,如果有直接进入第8步,否则进入第2步。
2 如果没有父类加载器,则要么Parent是根类加载器,要么本身就是根类加载器,则跳到第4步,如果父类加载器存在,则进入第3步。
3 请求使用父类加载器去载入目标类,如果载入成功则跳至第8步,否则接着执行第5步。
4 请求使用根类加载器去载入目标类,如果载入成功则跳至第8步,否则跳至第7步。
5 当前类加载器尝试寻找Class文件,如果找到则执行第6步,如果找不到则执行第7步。
6 从文件中载入Class,成功后跳至第8步。
7 抛出ClassNotFountException异常。
8 返回对应的java.lang.Class对象
缓冲区是否有class ---->无则请求父类加载器 ---->无则请求根类加载器 ---->无则请问当前类加载器
----------------------------------------------------------------------------------------------------------------------------
ClassLoader加载顺序:
=>Jvm类加载器加载JAVA_HOME/lib下的所有jar文件
=>Jvm扩展类加载器加载JAVA_HOME/lib/ext下的所有jar文件
=>系统类加载器加载指定classpath下所有jar文件
=>自定义类加载器加载继承官方提供的ClassLoader类的自定义实现加载器class文件。
----------------------------------------------------------------------------------------------------------------------------
类加载的顺序是
加载->链接(验证+准备+解析)->初始化(使用前的准备)->使用->卸载
Jvm会在启动的时候去加载系统所必须的JAVA_HOME/lib下的所有jar文件,
Jvm对于第三方类会才用懒加载的方式,即:用到的时候再进行加载,加载完成会放入缓存,以便后续使用。
面试题:
在自己的代码中,可以创建一个java.lang.String对象吗?如果可以,这个对象是否可以被类加载器加载?
可以创建,但是不能被加载到。
因为,双亲委派模式会保证父类加载器先加载类,就是BootStrap(启动类)加载器加载jdk里面的java.lang.String类,而自定义的java.lang.String类永远不会被加载到
转载:https://www.cnblogs.com/TravisGrady/p/10383119.html
https://blog.csdn.net/m0_38075425/article/details/81627349