从萌新的角度理解Java类加载机制
2018-08-11 本文已影响43人
涂印
类加载机制
本文主要是对java中类加载机制的入门级别文章,主要介绍类加载机制基本概念,以及类加载机制主要内容。本文按照结构组织如下:
- 类加载机制是什么
- 类加载机制主要内容
一丶类加载机制什么?
java程序从静态文本到动态执行的过程java中的类加载机制,从字面意思就不难理解。就是描述class文件加载到jvm的主要过程,class文件是对java类的描述,加载java类的过程就是加载class文件的过程。
类加载机制是围绕ClassLoader这个核心类展开的,classLoader就是类加载机制中的核心类。classLoader有如下几个主要的方法:
classLoader的核心方法.png
- defineClass:是将字节码加载到JVM内存中,解析成Class对象的方法。
- findClass: 该方式解析指定路径下的class文件生成Class对象的方法。一般defineClass方法和findClass是组合使用的,在findClass方法中依据指定路径,获取字节流,然后代用defineClass方法进行解析。
- resolveClass:解析继承关系上的的父类,以及所引用的类,是一个递归解析的过程,在对象正真被实例化的时候,该方法被调用。
- loadClass:该方法是上述所有方法的一站式解决方案,也是JVM自带类加载机制。如果调用loadClass方法加载类,是按照JVM默认的规则加载类,如果需要定制类加载器,则通过重写上述的三个方法可以达到效果
二丶类加载记住的主要内容
1. 谁来负责class文件的加载
在java代码中,每个定义的类都是由classloader加载进来的。JVM中的类加载器之间的关系组织结构和类的继承关系有些相似,都是一层层的,一个类加载器有父加载器,父加载器下面有许多子加载器。JVM主要提供三层类加载器:
1.1 类加载器组织结构
- 第一层:Bootstrap ClassLoader,这个类加载器,主要复杂加载JVM自身工作所需要的类。其他人都访问不到这个类加载器,是一个相对独立的类加载,其上没有父加载器,也没有子加载器
- 第二层:ExtClassLoader,这类加载是应用层能够访问到的顶层类加载器,可以认为其没有父加载器,只有子加载器。其主要负责加System.getProperty("java.ext.dirs")目录下的类。
-第三层:AppClassLoader,这个类加载器就是我们最常接触的类加载器,用来接在classpath路径下类的加载器。其父加载器是ExtClassLoader.
特别注意,从逻辑上可以定义第四层类加载器: - 第四层:自定义classLoader,该层不是JVM自带的类加载器,而是我们自定义的类加载器,在整个类加载的组织结构中,可以理解为第四层,其父加载器是AppClassLoader.
类加载器的组织结构 在熟悉类加载器组织结构后,我们还不能回答究竟是谁负责加载java类。在介绍完上级委托加载机制(双亲委托加载机制)后,就可以从众多classLoader中找到合适的类加载器加载java类了。
1.2 上级委托加载机制
上级委托加载机制图中的类加载器1是类加载器2的父加载器,从上往下依次类推。
- 向上询问:当我们使用类加载器4加载目标对象时,并不一定是类加载器4来负责该类的加载,类加载器4在确保目标类未被加载后,会将加载请求传递给其父加载器classloader3。classloader3会继续重复和classloader4相同的工作,向其父加载器传递加载请求,加载请求最后被传递给顶层加载器classloader1.。在该过程中如果某层加载器发现该类已加载了,则结束加载过程,确保不重复加载。如果顶层加载机制受理了加载请求,此次加载过程就结束了。**这个过程,
- 向下委派 如果顶层加载机制不受理该次加载请求,其会将类加载请求按原路遣返,沿途加载器将会依次检查是否受理该次类加载请求,最后由受理加载器加载目标类。
二丶类加载过程
上级委托机制回答了是谁负责加载类的这个问题,阅读完这一节后,就可以回答JVM加载类的一般过程了。
JVM加载类的阶段
- 第一阶段:该阶段的主要工作是定义去哪儿找class文件,并且通过字节流的形式将class文件加载到内存中。
- 第二阶段:该阶段细分为三个小阶段
- 字节码验证:类加载对加载的字节码,要做许多验证,确保class文件格式正确,行为正确。
- 类准备:在该阶段准备描述类中字段,方法以及实现接口所需要的数据结构,
- 解析:在这个阶段类加载器会将类中引用的所有相关类都加载进去,并且这是一个递归的过程。
- 第三阶段:初始化class对象,在这个阶段静态变量将初始化,静态代码块也是在这个时候执行的。
三丶定制类加载器
了解类加载机制的基本原理后,我们可以看看类加载机制在实际开发中的一些用途
- 在自定义路径下查找class类文件,当我们需要的class文件,不是在classpath路径下时,就需要自己实现一个类加载器来加载指定路径下的class文件。
- 对要加载的类做特殊的处理,在网络传输类信息时,一般会对类的字节码加密。在加载到JVM之前需要对类的字节码解密后再按传统方法加载,这个过程就可以通过自定义类加载器实现
- 类加载器一个比较常见的应用就是热部署,检查到已经加载的class文件已经修改的时候,重新加载这个类,以实现热部署。