JVM类加载类的分类
JVM类加载类的分类虚拟机自带的加载器启动类加载器(引导类加载器,Bootstrap ClassLoader)这个类加载使用C/C++语言实现的,嵌套在JVM内部。它用来加载Java中的核心库((JAVA_HOME/jre/lib/rt.jar、resources.jar或sun.boot.class.pa路径下的内容),用于提供JVM自身需要的类)并不继承自java.lang.classLoad
JVM类加载类的分类
虚拟机自带的加载器
-
启动类加载器(引导类加载器,Bootstrap ClassLoader)
- 这个类加载使用C/C++语言实现的,嵌套在JVM内部。
- 它用来加载Java中的核心库((JAVA_HOME/jre/lib/rt.jar、resources.jar或sun.boot.class.pa路径下的内容),用于提供JVM自身需要的类)
- 并不继承自java.lang.classLoader,没有父加载器。
- 加载扩展类和应用程序类加载器,并指定为他们的父类加载器。
出于安全考虑,Bootstrap启动类加载器只加载sun等开头的类
-
扩展类加载器(Extension classLoader)
- Java语言编写,由sun.misc.Launcher$ExtClassLoader实现。
- 派生于classLoader类
- 父类加载器为启动类加载器
- 从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安
装目录的jre/lib/ext子目录(扩展目录)下加载类库。如果用户创
建的JAR放在此目录下,也会自动由扩展类加载器加载。
-
应用程序类加载器(系统类加载器,AppclassLoader)
- java语言编写,由sun.misc.Launcher$AppClassLoader实现
- 派生于classLoader类
- 父类加载器为扩展类加载器
- 它负责加载环境变量classpath或系统属性java.class.path指定路径下的类库
- 该类加载是程序中默认的类加载器,一般来说,Java应用的类都是由
它来完成加载 - 通过classLoader#getsystemClassLoader()方法可以获取到该
类加载器
-
用户自定义类加载器
在Java的日常应用程序开发中,类的加载几乎是由上述3种类加载器相互
配合执行的,在必要时,我们还可以自定义类加载器,来定制类的加载方
式。 -
为什么要自定义类加载器?
隔离加载类
修改类加载的方式
扩展加载源
防止源码泄漏
图解:
代码如下:
package com.lbl.ClassLoaderTest;
public class ClassLoaderTest {
public static void main(String[] args) {
//获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);//sun.misc.Launcher$AppCLassLoader@18b4aac2
//获取其上层:扩展类加载器
ClassLoader extClassLoader = systemClassLoader.getParent();
System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLdader@1540e19d
//获取其上层:获取不到引导类加载器
ClassLoader bootstrapClassLoader = extClassLoader.getParent();
System.out.println(bootstrapClassLoader);//null
//对于用户自定义类来说:默认使用系统类加载器进行加载
ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
System.out.println(classLoader);// sun.misc.Launcher$AppClassLoader@18b4aac2
ClassLoader classLoader1 = String.class.getClassLoader();
//String类使用引导类加载器进行加载的。--->Java的核心类库都是使用引导类加载器进行加载的。
System.out.println(classLoader1);//null
}
}
运行结果:
再来测试一下引导类加载器:
代码:
package com.lbl.ClassLoaderTest;
import java.net.URL;
public class ClassLoaderTest02 {
public static void main(String[] args) {
System.out.println("***********启动类加载器***********");
//获取BootstrapCLassLoader能够加载的api的路径
URL[] urLs = sun.misc.Launcher.getBootstrapClassPath().getURLs();
for (URL element : urLs) {
System.out.println(element.toExternalForm());
}
}
}
运行效果:
找到file:/C:/Program%20Files/Java/jdk1.8.0_172/jre/lib/jsse.jar文件,然后解压,进入com.sun.net.ssl.internal.ssl文件夹,找到Provider.class如下图:
然后添加如下代码:
//从上面的路径中随意选择一个类,来看看他的类加载器是什么:
ClassLoader classLoader = Provider.class.getClassLoader();
System.out.println(classLoader);
完整代码如下:
package com.lbl.ClassLoaderTest;
import java.net.URL;
import java.security.Provider;
public class ClassLoaderTest02 {
public static void main(String[] args) {
System.out.println("***********启动类加载器***********");
//获取BootstrapCLassLoader能够加载的api的路径
URL[] urLs = sun.misc.Launcher.getBootstrapClassPath().getURLs();
for (URL element : urLs) {
System.out.println(element.toExternalForm());
}
//从上面的路径中随意选择一个类,来看看他的类加载器是什么:
ClassLoader classLoader = Provider.class.getClassLoader();
System.out.println(classLoader);
}
}
再来测试一下扩展类加载器:
代码如下:
package com.lbl.ClassLoaderTest;
public class ClassLoaderTest03 {
public static void main(String[] args) {
System.out.println("*********扩展类加载器*********");
String extDirs = System.getProperty("java.ext.dirs" );
for (String path : extDirs.split(";"))
System.out.println(path);
}
}
运行效果:
找到C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext文件夹,图片如下:
解压:sunec.jar,进入sunec\sun\security\ec找到CurveDB.class,如下图:
添加好下代码:
//在上面的路径中随意挑选一个类,来看看他有类加载器是什么
ClassLoader classLoader = CurveDB.class.getClassLoader();
System.out.println(classLoader);
完整代码如下:
package com.lbl.ClassLoaderTest;
import sun.security.ec.CurveDB;
public class ClassLoaderTest03 {
public static void main(String[] args) {
System.out.println("*********扩展类加载器*********");
String extDirs = System.getProperty("java.ext.dirs" );
for (String path : extDirs.split(";"))
System.out.println(path);
//在上面的路径中随意挑选一个类,来看看他有类加载器是什么
ClassLoader classLoader = CurveDB.class.getClassLoader();
System.out.println(classLoader); //sun.misc.Launcher$ExtClassLoader@4554617c
}
}
输出效果:
更多推荐
所有评论(0)