JVM类加载机制
JVM把描述类的数据从 Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是虚拟机的类加载机制。
在Java语言里面,类型的加载、连接和初始化过程都是在程序运行期间完成的
Java类加载过程
当程序主动使用到某个类时,如果该类未被加载进内存中,则系统会通过加载、连接(验证、准备和解析)、初始化三个步骤对该类进行初始化操作。
- 类的加载:
类加载是指通过类的全限定名将类的class文件(字节码文件)载入内存中,并为之创建一个java.lang.Class对象(字节码对象),作为这个类的方法和数据访问入口。
类的加载过程由类加载器(ClassLoader)完成,类加载器通常由JVM提供(系统加载器),我们也可以继承ClassLoader来自定义加载器。
不同的类加载器可以实现加载本地字节码文件,jar包中的字节码文件、通过网络加载字节码等。 - 类的连接:
当类加载进内存后,系统会为之创建一个Class对象,接着把二进制数据合并到JRE中。类的连接分为验证、准备、解析三个步骤:- 验证:检测被加载的类是否有正确的内部结构,即字节码中的信息是否符合JVM的要求。
- 准备:负责为类的static变量分配内存,并初始化值。这些静态变量分配的内存都在方法区中。
- 解析:把类中的二进制数据中的符号引用替换为直接引用。
- 类的初始化:
在此阶段,JVM负责对类进行初始化,主要是对static变量进行初始化
类的初始化包含以下几个步骤:- 如果该类还未被加载和连接、则程序先加载并连接该类。
- 如果该类的直接父类还未被初始化则先初始化该父类;如果用到某个类,则先加载所依赖的类。
- 如果类中有出初始化语句(静态代码块)则系统依次执行这些初始化语句。
Java类加载器
类加载器用来完成类加载过程中的类加载步骤。一般情况下,我们不需要与类加载器进行交互,JVM的默认操作足以满足大多数情况。
获取ClassLoader对象的方式:
- 1、使用Class对象获取ClassLoader对象:
类名.class.getClassLoader - 2、使用当前线程的ClassLoader对象:
Thread.currentThread().getContextClassLoader - 3、使用系统的ClassLoader,即系统入口点的ClassLoader对象:
ClassLaoder().getSystemClassLoader()
Java类加载顺序
当类加载器加载类时,会优先加载父类;其次时类中所依赖的其他类。在加载每个类时,优先初始化静态成员,当成员初始化后才会执行构造方法。静态成员的初始化与静态代码块的执行发生在类加载的时候。类对象的创建与静态代码块的调用都会触发JVM的默认行为加载类。