没有合适的资源?快使用搜索试试~ 我知道了~
Java类加载器(ClassLoader)1
需积分: 0 0 下载量 130 浏览量
2022-08-03
19:05:55
上传
评论
收藏 691KB PDF 举报
温馨提示
试读
11页
如果户创建的JAR放在此录下,也会动由扩展类加载器加载.应程序类加载器(系统类加载器,Application ClassLoader)java语编写,由sun.
资源详情
资源评论
Java类加载器(ClassLoader)
类加载分类
在虚拟机提供了3种类加载器,引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension
ClassLoader)、系统类加载器(System ClassLoader)(也称应⽤程序类加载器(Application
ClassLoader)),我们在程序⾥也可以⾃定义类加载器,下⾯分别介绍。
引导类加载器(Bootstrap ClassLoader)
使⽤C/C++语⾔实现,在JVM内部。
它⽤来加载 Java 的核⼼库(JAVA_HOME/jre/lib/rt.jar、resources.jar或sun.boot.class.path路径下的内容)。
不继承 java.lang.ClassLoader,没有⽗加载器。
加载扩展类和应⽤程序类加载器。并指定他们的⽗类加载器。
出于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类。
加载内容如下
扩展类加载器(启动类加载器,Extension ClassLoader)
Java语⾔编写,由sun.misc.Launcher$ExtClassLoader实现。
派⽣于ClassLoader类
⽗类加载器为引导类加载器
从java.ext.dirs系统属性所指定的⽬录中加载类库,或从JDK的安装⽬录的jre/lib/ext⼦⽬录(扩展⽬录)下
加载类库。如果⽤户创建的JAR放在此⽬录下,也会⾃动由扩展类加载器加载.
应⽤程序类加载器(系统类加载器,Application ClassLoader)
java语⾔编写,由sun.misc.Launcher$AppClassLoader实现
派⽣于ClassLoader类
⽗类加载器为扩展类加载器
它负责加载环境变量classpath或系统属性java.class.path指定路径下的类库
该类加载是程序中默认的类加载器,⼀般来说,Java应⽤的类都是由它来完成加载
获取加载器加载内容⽅法如下
⾃定义类加载器
为什么要⾃定义类加载器?
隔离加载类
修改类加载的⽅式
扩展加载源
防⽌源码泄漏
JAVA_HOME/jre/lib/resources.jar
JAVA_HOME/jre/lib/rt.jar
JAVA_HOME/jre/lib/sunrsasign.jar
JAVA_HOME/jre/lib/jsse.jar
JAVA_HOME/jre/lib/jce.jar
JAVA_HOME/jre/lib/charsets.jar
JAVA_HOME/jre/lib/jfr.jar
JAVA_HOME/jre/classes
// 获取引导类加载器加载url
URL[] bootUrls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
// 获取扩展类加载器加载url
URL[] extUrls = ((URLClassLoader)
ClassLoader.getSystemClassLoader().getParent()).getURLs();
// 获取系统类加载器加载url
URL[] systemUrls = ((URLClassLoader) ClassLoader.getSystemClassLoader()).getURLs();
⽤户⾃定义类加载器实现步骤
通过继承 java.lang.ClassLoader类的⽅式实现⾃⼰的类加载器,以满⾜⼀些特殊的需求。
在JDK1.2之前,在⾃定义类加载器时,总会去继承ClassLoader类并重写loadClass()⽅法,从⽽实现⾃定义
的类加载类,但是在JDK1.2之后已不再建议⽤户去覆盖loadclass()⽅法,⽽是建议把⾃定义的类加载逻辑写在
findclass()⽅法中
在编写⾃定义类加载器时,如果没有太过于复杂的需求,可以直接继承URLClassLoader类,这样就可以避免
⾃⼰去编写findclass()⽅法及其获取字节码流的⽅式,使⾃定义类加载器编写更加简洁。
ClassLoader
ClassLoader类,它是⼀个抽象类,其后所有的类加载器都继承⾃ClassLoader(不包括启动类加载器)
作⽤
java.lang.ClassLoader类的基本职责就是根据⼀个指定的类的名称,找到或者⽣成其对应的字节代码,然后从这些
字节代码中定义出⼀个Java类,即java.lang.Class类的⼀个实例。
常⽤⽅法总结
getParent():返回该类加载器的⽗类加载器
forName(String className):通过类名称获取已经初始化的java.lang.Class类的实例
loadClass(String name):通过类名称加载类,返回java.lang.Class类的实例,该⽅法中的逻辑就是双亲委派
模式的实现
此⽅法负责加载指定名字的类,⾸先会从已加载的类中去寻找,如果没有找到;从parent
ClassLoader[ExtClassLoader]中加载;如果没有加载到,则从Bootstrap ClassLoader中尝试加载
(findBootstrapClassOrNull⽅法), 如果还是加载失败,则⾃⼰加载。如果还不能加载,则抛出异常
ClassNotFoundException
findClass(String name):通过类名称查找类,返回java.lang.Class类的实例,需要⾃⼰实现
findLoaderClass(String name):通过类名称查找已经被加载的类,返回java.lang.Class类的实例
defineClass(String name, byte[] b, int off, int len):把字节数组b中的内容转换为⼀个Java类,返回
java.lang.Class类的实例
resolveClass(Class<?> c):链接指定的⼀个Java类
⽅法源码
loadClass
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 先从缓存查找该class对象,找到就不⽤重新加载
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
剩余10页未读,继续阅读
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0
最新资源