Java虚拟机加载类的全过程包括:加载、验证、准备、解析、初始化。验证、准备、解析叫链接过程。今天咱们讲加载。
首先明确“加载”是“类加载”的一个过程,不要混淆。加载过程当中,虚拟机须要完成下列三个事情:java
虚拟机的这三点要求不算具体,所以虚拟机实现与具体应用的灵活度都是至关大的。就拿第一条说,他仅仅要求“经过一个类的全限定名获取定义此类的二进制字节流”,并无指明二进制字节流要从Class文件获取,也没说要怎样获取,从哪里获取。因此说java虚拟机的设计团队在加载阶段搭建了一个很广阔的舞台,许多举足轻重的java技术都创建在这个舞台上,好比:web
相对于类加载过程的其余阶段,一个非数组类的加载阶段(准确的说,是加载阶段中获取二进制字节流的动做,有的加载阶段不获取二进制字节流)是开发人员 可控性最强的,由于加载阶段便可以使用系统提供的引导类加载器来完成,也能够由用户自定义的类加载器去完成,开发人员能够经过定义本身的类加载器去控制字节流的获取方式(即重写一个类的loadClass方法)。数据库
对于数组类而言,状况不一样。数组类自己不经过类加载器建立,他是由java虚拟机直接建立。但数组类与类加载器的关系任然很密切,由于数组类的元素类型(指的是数组去掉全部维度的类型)最终要靠类加载器建立,一个数组类(下面简称C)建立过程遵循如下规则:数组
加载阶段完成以后,虚拟机外部的二进制字节流就按照虚拟机所需的格式存储在方法区之中,方法区中的数据存储格式由虚拟机实现自行定义,虚拟机规范未规定此区域的具体数据结构。而后在内存中实例化一个java.lang.Class类的对象(并无明确规定是在java堆中,对于HotSpot虚拟机而言,Class对象比较特殊,他虽然是对象,可是放在方法区中),这个对象将做为程序访问方法区中的这些类型数据的外部接口。
加载阶段与链接阶段的部份内容(如一部分字节码文件格式验证动做)是交叉进行的,加载阶段还没有完成,链接阶段可能开始了,可是这些夹在加载阶段之中进行的动做,任然属于链接阶段的内容,这两个阶段的开始时间任然保持着固定的前后顺序。网络