Java类加载机制

Java 类加载过程

JVM是有序地、根据需要来加载相应的类。程序是依靠多个JAVA类共同协作完成的,每一个程序都需要依赖其他的类来完成某项功能。JVM会根据classpath的配置来加载程序的所有类。如果在classPath指定的路径上都没有找到类,就会报ClassNotFountException。classpath是由多个路径组成的,排在前面的优先级越高。
为了让程序正常有序地运行,需要给类的加载定义一套规范。Java的类加载器ClassLoader就是用来控制类的加载规则的工具。

ClassLoder

ClassLoader是负责查找字节码、加载字节码、校验字节码的应用程序。位于java.lang.ClassLoder。
1) load(String className) 根据名字加载一个类,返回类的实例。 
2)defineClass(String name, byte[] b, int off, int len) 第二个形参是一个字节流,把这个字节流转换成Class类,然后注册到虚拟机中。
3)findClass(String name) 查找一个类
4)findLoadedClass(String name) 在已加载的类中,查找一个类。
5)**成员变量:ClassLoader parent**;

java给类加载器定义了一套完整的规范,叫做四级类加载器。

== 很多框架文件热部署的实现原理:使用java的java.nio.file.WatchService, 监控jar文件是否有变动,如有变动,则使用URLClassLoader动态的加载jar包中的文件,实现热部署。=> 即,重复加载某个路径,实现程序热部署
URLClassLoader ucl = new URLClassLoader(file:文件路径);
while(true) {
ucl.load(“类长名”);
}
URLClassLoader 可以动态增加程序的类加载路径,克服前三个类加载器的静态路径的缺点。

两个不同的类加载器,加载了同一个类,在JVM中,也会把这两个类当做是不同的类,他们创建的对象不可以互相转化。所以同一个类可以被不同层级的类加载器加载,但JVM会认为这是两个类,不会认为是同一个类。因此,尽量保证在程序运行当中,某一个类只由一个类加载器加载。除非这同一个类是由两个不同的任务分支执行的。

通过继承ClassLoader类,重写findClass方法,可以自定义类加载器,通过调用defineClass可以将字符流加载为Class,注册到虚拟机中。可以在加载类的过程中,修改Class字节码,加解密等。

=》
JVM的类加载机制,主要为了保障核心类加载的正确性、安全性,同时兼顾类加载的动态性,java提出了四级类加载器以及双亲委托机制。
java的四级类加载器、双亲委托机制、自定义类加载路径(URLClassLoader)、自定义类加载器。
四级类加载器,最上层的是BootStrap classLoader, 负责加载rt.jar中的类;第二层是Extension ClassLoader,负责加载jre/lib/ext目录下的类;第三层是APP ClassLoader, 负责加载classpath指定的类路径的加载器。这三个类加载器是比较固定的,他们加载的类、加载的路径都是静态的,比较固定的。另外一个是用户自定义的类加载器,可以在加载的过程中对字节码做一些操作,或者动态的增加类加载的路径,给程序提供了类加载的动态性。
四级类加载器里面,又采用了双亲委托机制,每个类加载器加载类的时候,优先都是委托他的父类加载器来加载,如果父类加载器加载不了,才有本类加载器来加载。这样的体系结构通过逐级加载,确保核心类是可信的,因为所有的JDK核心的类肯定都是有BootStrap类加载器加载的。
JVM提供的类动态加载机制包括:
1)通过指定虚拟机参数-Xbootclasspath ,将jar包或目录提高到bootstrap级别。常规的jar包或目录通常是配置在classpath上,通常是由app类加载器来加载。这样类的加载优先级就更高一些。
2)使用ServiceLoader和SPI机制,可以实现上层加载器加载的类可以访问下层加载器加载的类。如java核心类库的java.sql.Driver类加载到mysql具体的驱动类。mysql的类是由app classloader加载的,java核心类是由bootstrap加载的。
3)使用URLClassloader可以在运行时增加新的classpath路径。通常classpath在程序运行之前就已经固定下来了,如果想在程序运行中增加新的类搜索路径,就可以使用URLClassloader,调用addUrl方法,或者在构造器中指定url,就可以使用新的class路径来加载
4)使用自定义的classloader, 通过重新loadclass、findclass方法,可以动态的加载字节码,也可以在字节码加载的过程中,进行修改校验等操作。

整个JVM类装载的过程,有三个步骤:
1)加载
2)链接
a) 验证,字节码是否满足规范要求
b) 准备,分配内存,常量初始化
c) 解析,解析类、接口、方法、字段的符号引用
3)初始化:执行类的初始化方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值