一、类的加载可以分为加载、连接、初始化 三个步骤
类的加载:
- 1、类的加载指的是将类的class文件加载到内存中,并且为之创建一个java.lang.Class对象。
- 2、JVM提供类加载器去加载类。JVM提供的类加载器通常称为系统类加载器,可以继承ClassLoader基类去创建自己的类加载器。
- 3、程序中所有的类实际上也是实例,他们都是java.lang.Class实例。
- 4、使用不同的类加载器可以从不同来源来加载类的二进制数据(本地文件系统、JAR包、网络、java源文件动态编译进行加载)。
类的连接:
- 1、连接阶段负责把类的二进制文件数据合并到JRE中。
- 2、可以分为三个阶段:
- 验证:验证类结构,是否和其他类协调一致。
- 准备:为类的类变量分配内存,设置默认初始值。
- 解析:将类的二进制文件中的符号引用替换为直接引用。
类的初始化:
- 1、主要对类变量初始化,(声明类变量时指定初始值、使用静态初始化块)。
- 2、步骤:
- 当这个类没有加载和连接,则先加载并且连接。
- 当这个类的直接父类没有被初始化,则先初始化。
- 当类中有初始化语句,则系统依次执行初始化语句。
- 3、类初始化时机:
- 创建类的实例(new、反射、反序列化)。
- 调用某个类的静态方法。
- 访问某个类或者接口的类变量,或者为该类变量赋值。
- 初始化某个类的子类。
注意:对于一个final型的类变量,如果在编译时期能确定其值,则java编译器在编译时期就会在这个类变量出现的地方替换成它的值。那么程序使用该
静态变量也不是导致初始化。 二、类加载器- 1、一旦一个类被加载到JVM中,同一个类就不会被载入了,这里同一个类是指:
一个类用全限定类名作为标识,在jvm中,一个类用全限定类名和其类加载器作为唯一标识,
- 2、JVM启动时会形成三个类加载器组成的初始类加载器层次结构:
- Bootstrap ClassLoader :根类加载器,负责加载Java的核心类比如rt.jar,由jvm自身实现,不是java.lang.ClassLoader的子类。
- Extension ClassLoader : 扩展类加载器,负责加载jre的扩展目录,.\jre1.8.0_181\lib\ext 中的类。
- System ClassLoader :系统类加载器,负责加载由CLASSPATH环境变量所指定的jar包和类路径。
- 3、类加载机制:
- 全盘负责:当一个类加载器负责一个类的加载时,该类所依赖的和引用的其他类也将由该类加载器负责载入,除非显示声明。
- 父类委托:尝试让父类加载器加载,当父类加载器无法加载时才让从自己的类路径中加载。
- 缓存机制:所有加载过的Class都会被缓存。