Java基础之ClassLoader

前沿:作为Android开发工程师,特别是做到后期框架层面,很容易接触到classloader,往往还是对这个词的理解有所模糊,这边在java的角度解释下ClassLoader,包括下一篇着重分析下在Android中有哪些ClassLoader类,以及在当下比较火的插件化、热更新技术中是如何运用的。

目录:整体分“什么是类加载器”、“类加载器的类型”、“双亲委托模型”、“类的加载过程”四点做简单的说明。

一、什么是类加载器

java虚拟机是运行时是不会一次性把所有的class文件加载到内存中的,如果一次性加载会对内容有很大的消耗,所有就有了动态加载的机制产生,而ClassLoader就是主要负责动态加载class文件到内存中的,也正需要加在到内存中,才可以被其它的class所调用,所以在java中classloader是一个重中之重的地位。(什么是class文件?恩....?..?这个问题好难!)

二、类加载器类型

Bootstrap ClassLoader 最顶层的加载类,属于启动类的加载器,主要加载核心类库,%JRE_HOME%\lib下的rt.jar、resources.jar、charsets.jar和class等。另外需要注意的是可以通过启动jvm时指定-Xbootclasspath和路径来改变Bootstrap ClassLoader的加载目录。比如java -Xbootclasspath/a:path被指定的文件追加到默认的bootstrap路径中。我们可以打开我的电脑,在上面的目录下查看,看看这些jar包是不是存在于这个目录。

Extention ClassLoader 扩展的类加载器,加载目录%JRE_HOME%\lib\ext目录下的jar包和class文件。还可以加载-D java.ext.dirs选项指定的目录。 

App ClassLoader也称为SystemAppClass 加载当前应用的classpath的所有类。

注意: Bootstrap ClassLoader 不是一个普通的java类,它不继承我们的抽象类ClassLoader,它的底层是C++编写。


源码分析

首先找到:sun.misc.Launcher,它是一个java虚拟机的入口应用。

Java基础之ClassLoader_第1张图片
sun.misc.Launcher部分源码
Java基础之ClassLoader_第2张图片
BootstrapClassLoader加载jar

1. Launcher初始化了ExtClassLoader和AppClassLoader。 

2. Launcher中并没有看见BootstrapClassLoader,但通过System.getProperty("sun.boot.class.path")得到了字符串bootClassPath,这个应该就是BootstrapClassLoader加载的jar包路径。(其实全是JRE目录下的jar包或者是class文件。)

具体的其它源码有兴趣的小伙伴可以自行查看

三、双亲委托模型

Java基础之ClassLoader_第3张图片
委托模式

        一个类加载器查找class和resource时,是通过“委托模式”进行的,它首先判断这个class是不是已经加载成功,如果没有的话它并不是自己进行查找,而是先通过父加载器,然后递归下去,直到Bootstrap ClassLoader,如果Bootstrap classloader找到了,直接返回,如果没有找到,则一级一级返回,最后到达自身去查找这些对象。这种机制就叫做双亲委托。 


Java基础之ClassLoader_第4张图片
详细流程

四、类加载的过程

    类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。它们开始的顺序如下图所示:


Java基础之ClassLoader_第5张图片
类加载过程

   其中类加载的过程包括了加载、验证、准备、解析、初始化五个阶段。在这五个阶段中,加载、验证、准备和初始化这四个阶段发生的顺序是确定的,而解析阶段则不一定,它在某些情况下可以在初始化阶段之后开始,这是为了支持Java语言的运行时绑定(也称为动态绑定或晚期绑定)。另外注意这里的几个阶段是按顺序开始,而不是按顺序进行完成,因为这些阶段通常都是互相交叉地混合进行的,通常在一个阶段执行的过程中调用或激活另一个阶段。

Java中的绑定:绑定指的是把一个方法的调用与方法所在的类(方法主体)关联起来,对java来说,绑定分为静态绑定和动态绑定

静态绑定:即前期绑定。在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现。针对java,简单的可以理解为程序编译期的绑定。java当中的方法只有final,static,private和构造方法是前期绑定的。

动态绑定:即后期绑定,也叫运行时绑定。在运行时根据具体对象的类型进行绑定。在java中,几乎所有的方法都是后期绑定的。

由Java虚拟机自带的类加载器所加载的类,在虚拟机的生命周期中,始终不会被卸载。

总结:

      ClassLoader是用来动态的加载class文件到虚拟机中,并转换成java.lang.class类的一个实例,每个这样的实例用来表示一个java类,我们可以根据Class的实例得到该类的信息,并通过实例的newInstance()方法创建出该类的一个对象,除此之外,ClassLoader还负责加载Java应用所需的资源,如图像文件和配置文件等。应用此技术可以做到web应用的热部署,就是在应用正在运行的时候升级软件,不用重启系统。另外在Android开发中通过自定义ClassLoader可以动态加载类,从而做到插件化、热修复等等。

下一次和大家一起探讨下基于Android的ClassLoader,如DexClassLoader、Pathclassloader以及资源加载器AssetManager。

你可能感兴趣的:(Java基础之ClassLoader)