脚本宝典收集整理的这篇文章主要介绍了

Java中类加载机制

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。

类加载流程:

Java中类加载机制-脚本宝典
从上面这幅图可以看出一个类从加载到卸载有7个阶段,其中验证、准备和解析这三个步骤统称为连接。类加载的过程一定会经过加载、验证、准备、初始化和卸载这5个过程,解析和使用则不一定。还有一点要注意的是,并不是每个步骤完全执行完之后才会调用下一个步骤,它会在一个步骤执行的过程中就调用下一个步骤,只是开始的时候一定会按这个顺序。

类加载每个步骤的操作:

一、加载
加载过程会做下面三件事。

  1. 通过一个类的全限定名来获取定义这个类的二进制字节流。
  2. 将这个字节流的静态存储结构转化为方法区运行时的数据结构。
  3. 在内存中为这个类生成一个java.lang.Class对象,作为方法区这个类的访问入口。

二、验证
验证是为了确保加载进来的Class文件的字节流里的内容是符合当前虚拟机的要求,不会危害虚拟机自身的安全,比如一些非法的语句之类的,会进行下面4步验证。

  1. 文件格式验证,验证字节流是否符合Class文件格式的规范,可以被当前虚拟机处理。
  2. 元数据验证,对加载进来的类的元数据进行语义验证,保证都符合Java语言规范。
  3. 字节码验证,这一步是在确保元数据符合Java语言规范后再验证它是否有非法的,不合逻辑的地方。比如调用一个方法返回int,却声明一个double变量去接这个值。
  4. 符号引用验证,就是对常量池中的各种符号引用进行验证,看这些符号引用是否能被当前类访问到。

三、准备
这个阶段就是给类变量分配内存并且设置初始化值,注意这里只是会分配内存给类变量,实例变量只有在对象初始化的时候才会分配。
四、解析
在这个阶段是把符号引用替换为直接引用的过程。
五、初始化
初始化是是类加载过程中的最后一步,它会根据代码中的定义再去初始化类变量和其他的资源,到这一步就表示整个类已经初始化完成了。

类加载器:

类加载器执行的操作就是上述加载阶段做的事,通过一个类的全限定名来获取定义这个类的二进制字节流,类加载器可以分为下列三种。

  1. 启动类加载器,它负责加载存放在<JAVA_HOME>lib目录下或者是被-Xbootclasspath参数所指定的路径中的类库。
  2. 扩展类加载器,负责加载存放在<JAVA_HOME>libext目录或者是java.ext.dirs系统变量所指定的路径中的类库,这个加载器我们可以直接使用。
  3. 应用程序类加载器,也称为系统类加载器。负责加载用户类路径(ClassPath)上所指定的类库,这个加载器我们也可以直接使用。

双亲委派模型:

clipboard.png

双亲委派模式的结构就是上图所示,要求除了最顶层的启动类加载器之外其他的类加载器都要有自己的父类。这里的父类不是用继承实现的,是通过组合方式来复用父类类加载器。它的工作原理是当一个类加载器收到了类加载的请求,不会先自己去加载,而是先委派给父类加载器去执行,父类加载器如果也有它的父类就继续委派上去,直到最顶层的启动类加载器为止。而当父类没办法加载的时候再一层一层往下返回,让它的子类加载器去加载。


优点:
这样的好处在于让类加载器有一种优先级的层级关系。这里要提到一点,判断两个类是否相等,除了要判断是否是同一个Class文件加载的还需要看是不是同一个类加载器加载出来的。如果不是同一个类加载器加载的,即使是同一个Class文件加载出来的类也是不相同的。举个例子,比如java.lang.Object类,当它被加载的时候一定会被委派到最顶层的启动类加载器去加载。所以无论你拿什么类加载器去加载,最后得到的Object类都是同一个类。如果没有这种委派关系的话,都是Object类,但是由不一样的类加载器加载的,各自加载出来的Object类也不相同,会造成一片混乱。


这篇文章只是大致上讲了Java中类加载的过程和类加载器的设计。中间还有很多细节没有做详细说明。如果还想要再详细了解的话可以去看一下《深入理解Java虚拟机:JVM高级特性与最佳实践 第2版 》这本书,本篇文章的内容在这本书的第七章里有详细的解释。

总结

以上是脚本宝典为你收集整理的

Java中类加载机制

全部内容,希望文章能够帮你解决

Java中类加载机制

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过