JVM 进阶 (十四)——初识 JAVA 类加载机制
从本篇博文开始,我们就进入虚拟机类加载机制的学习了。那么什么是类加载呢?当我们写完一个 Java 类的时候,并不是直接就可以运行的,它还要编译成.class
(字节码)文件,再由虚拟机解释给当前的操作系统去执行。这些过程都是我们看不见的,我们能看见的也就是一个.class
文件。既然虚拟机要解释这些.class
文件给当前的操作系统听,那么他怎么获得这些.class
文件呢?虚拟机获得这些.class
文件的过程就是类加载了。
所以,总结来说就是:虚拟机将.class
文件从磁盘或者其他地方加载到内存,并同时对文件中的数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接识别的类型,这就是类加载机制!
首先我们来看看类的一个生命周期:
总共有加载、验证、准备、解析、初始化、使用和卸载七个阶段。其中前面的 5 个阶段就是我们要说的类加载机制了,验证、准备、解析阶段又统称为连接阶段。注意:解析阶段不一定会在准备阶段之后就执行,也有可能会在初始化阶段之后,这是为了支持 JAVA 的动态绑定的特性。
什么是动态绑定呢?相信大家都知道 JAVA 的 4 大特性吧:封装、继承、抽象、多态。其实多态就可以理解为动态绑定。多态的实现机制就是:**父类或者接口可以创建他们的子类或者实现类的实例对象。**简单的来说就是:父类可以 new 出子类,接口可以 new 出他的实现类。
多态通俗来说就是:父类 A 有一个方法 function(),子类 B,C 分别继承 A 并且重写 function(),当创建一个对象 A b = new B(); b.function()就调用 B 的 funciotn,假如你 new C(),那调用的就是 C 重写的 function。虚拟机怎么判断你使用的是哪个类的 function 就是动态绑定,这个现象就是多态。
装载的第一步就是要获得二进制的字节流,它可以从读.class 文件获得,也可以从网络中接收别人发送的字节流。反正只要符合虚拟机规定的字节流格式都可以进入这个阶段。
有了字节流之后,要进行装载还需要一个工具,那就是加载器了。加载器既可以使用系统提供的引导类加载器,也可以使用用户自己定义的加载器,只需要继承 ClassLoader,再重写 loadClass()方法就可以实现一个自己的简单加载器。
像上面的代码那样,就是一个简单的类加载器。当我们要自己加载某个类的时候,就可自己调用 loadClass 方法,参数通常为要加载类的全类名,再根据 name 获得文件,得到字节流后便可加载,示例代码如下:
一般的工作情况下我们不会自己去实现加载器,都是采用系统默认的加载器。绝大部分 Java 程序都会使用到系统提供的以下 3 种加载器:
Bootstrap ClassLoader
:启动类加载器。负责加载 JAVA_HOME/lib/里所有能被虚拟机识别的类(如:rt.jar)。无法被 Java 程序直接引用,由 C++实现,不是 ClassLoader 子类。Extension ClassLoader
:扩展类加载器。负责加载 java 平台中扩展功能的一些 jar 包,包括 JAVA_HOME/lib/ext/目录中的或 java.ext.dirs 系统变量指定目录下的所有类库。是 ClassLoad 的子类,开发者可以直接使用该加载器。App ClassLoader
:应用程序类加载器。负责加载 classpath 中指定的 jar 包及目录中 class。getSystemClassLoader()的返回值就是该加载器,开发者可以直接使用该加载器。
版权声明: 本文为 InfoQ 作者【No Silver Bullet】的原创文章。
原文链接:【http://xie.infoq.cn/article/53fcebcb3d15b7128824fbac4】。文章转载请联系作者。
评论