1.类加载是什么?
类加载器本质上是一段代码,这段代码执行后,可以从指定位置上把编译好的java类从硬盘上读取到内存
2.类加载器的种类?
类加载器是个总称,下面有很多不同终类,特点的个性化类加载器。
类加载器在Java中,被称为ClassLoader,同时这个ClassLoader,也是Java se api中提前写好一个类。这个类的作用就是用来代表类加载器的。
3.JVM中的类加载器:
启动类加载器 BootStrapClassLoader
- 注意这个类加载器不是Java代码实现的。
- 加载路径:C:\Program Files\Java\jdk1.8.0_74\jre\lib\
- 自动加载这个路径下的指定jar,例如:rt.jar
- 在java中,使用这个变量来代表启动类加载器加载的路径:sun.boot.class.payh
- 当我们电脑中运行后这个变量的结果为:
- C:\Program Files\Java\jdk1.8.0_74\jre\lib\resources.jar;
- C:\Program Files\Java\jdk1.8.0_74\jre\lib\rt.jar;
- C:\Program Files\Java\jdk1.8.0_74\jre\lib\sunrsasign.jar;
- C:\Program Files\Java\jdk1.8.0_74\jre\lib\jsse.jar;
- C:\Program Files\Java\jdk1.8.0_74\jre\lib\jce.jar;
- C:\Program Files\Java\jdk1.8.0_74\jre\lib\charsets.jar;
- C:\Program Files\Java\jdk1.8.0_74\jre\lib\jfr.jar;
- C:\Program Files\Java\jdk1.8.0_74\jre\classes
- 这个类加载器专门加载java系统中最重要同时也是最基本的类
扩展类加载器 ExtClassLoader:
- 这个类加载器是Java代码实现的
- 加载路径:C:\Program Files\Java\jdk1.8.0_74\jre\lib\ext\ 自动加载这个路径下jar包
- 在java中,使用这个变量来代表扩展类加载器加载路径:java.ext.dirs
- 电脑中运行后这个变量的结果为:C:\Program Files\Java\jdk1.8.0_74\jre\lib\ext
- 这个类加载器专门加载系统中额外添加的一些功能的jar包
应用类加载器 AppClassLoader:
- 这个类加载器是java代码实现的
- 加载路径:环境变量 classpath 中所有路径里面的class文件
- 在java中,使用这个变量来代表应用类加载器加载路径:java.class.path
- 电脑中运行后的结果为:jar/commons.jar;bin
- 这个对应的值,就是在运行代码时候,自己设置的classpath变量值
- 这个类加载器专门加载系统中用户自己编写的项目代码
自定义类加载器 XXXClassLoader:
ClassLoader appClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(appClassLoader);//sun.misc.Launcher$AppClassLoader@2a139a55
ClassLoader extClassLoader = appClassLoader.getParent();
System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLoader@7852e922
ClassLoader bootClassLoader = extClassLoader.getParent();
System.out.println(bootClassLoader);//null
注意:启动类加载在Java中无法表示,因为他不是java语言实现的,所以输出的是null
4.多个类加载器之间协同合作:
1).启动类加载器 bootstrapClassLoader
2).扩展类加载器 ExtClassLoader
3).应用类加载器 AppClassLoader
这三个类加载器共同协作,使用【双亲委托】的方式,把一个class文件加载到内存
如上图所示:
要运行Hello.class文件中的类,首先将加载任务给了AppClassLoader,然后AppClassLoader将任务给了自己的父类加载器ExtClassLoader,然后ExtClassLoader也会把这个加载任务委托给bootCLassLoader,然后bootstrapClassLoader就尝试去加载Hello这个类,但是在指定路径下并没有找到,然后这个任务就又交给了ExtClassLoader,这时候ExtClassLoader就尝试加载Hello这个类,但是在指定路径中也没找到,然后这个任务又交给了AppClassLoader,最后AppClassLoader从classpath中指定的路径里面找到并加载了这个Hello类,完美诠释向上委托,向下加载。
5.为什么要双亲委托呢?
双亲委托可以避免而已和系统中同包同名的类被加载到内存,替换系统中原有的基础,而导致系统崩溃的情况发生。
欢迎评论~