类加载机制及常用的类加载器
一、类加载的过程
1、加载
(1)通过类的全限定类名来获取该类的二进制字节流
(2)将字节流代表的静态存储结构转化为方法区运行时的数据结构
(3)在内存中生成一个代表该类的java.lang.Class对象,作为这个类的各种数据的访问入口
2、链接
确保Class文件的字节流中包含的信息符合虚拟机的要求,不会危害虚拟机的自身安全
(1)验证
-
格式验证
- 元数据验证
- 字节码校验
(2)准备
为类变量分配内存并设置类变量的初始值
这些变量所使用的内存都将在方法区中进行分配。
1、内存分配的仅包括类变量(被static修饰的变量),而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在Java堆中。
2、初始值“通常情况”下是数据类型的零值,假设一个类变量的定义为:
public static int value=123;
那变量value在准备阶段过后的初始值为0而不是123,因为这时候尚未开始执行任何Java方法,而把value赋值为123的public static指令是程序被编译后。
(3)解析
虚拟机将常量池中的符号引用替换为直接饮用
3、初始化
执行构造器中的代码
初始化阶段是执行类构造器<clinit>()方法的过程。<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的。
二、常用的类加载器
1、启动类加载器(Bootstrap ClassLoader)
用来加载java核心类库,无法被java程序直接引用
2、扩展类加载器(Extension ClassLoader)
它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载Java 类
3、系统类加载器(System ClassLoader)
它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。
可以通过ClassLoader.getSystemClassLoader()来获取它
4、用户自定义类加载器
通过继承java.lang.ClassLoader类的方式实现