类加载机制
一、类的加载可分为 加载、连接、初始化
类的加载:
• 1、含义:指将class文件载入内存中,并为之创建个java.lang.Class对象。
• 2、JVM提供类加载器去加载类。
• 3、程序中所有类都是实例,都为java.lang.Class实例。
• 4、使用不同的类加载器可以从不同来源加载类的二进制数据(本地文件系统、JAR包、网络、java源文件动态编译进行加载)。
类的连接:
• 1、连接阶段负责把类的二进制文件数据合并到JRE中。
• 2、分三阶段:
1. 验证:验证类结构,是否和其他类协调一致。
2. 准备:为类的类变量分配内存,设置默认初始值。
3. 解析:将类的二进制文件中的符号引用替换为直接引用。
类的初始化:
• 1、主对类变量初始化(example声明类变量时指定初始值、使用静态初始化块)。
• 2、步骤:
1. 若此类没加载和连接,则先加载并连接。
2. 若类的直接父类没有被初始化,则先初始化。
3. 当类中有初始化语句,则系统依次执行初始化语句。
• 3、类初始化时机:
1. 创建类的实例(new、反射、反序列化)。
2. 调用某个类的静态方法。
3. 访问某个类或者接口的类变量,或为该类变量赋值。
4. 初始化某个类的子类。
注意:对于一个final型的类变量,若在编译时期能确定其值,则java编译器在编译时期就会在这个类变量出现的地方替换成它的值。
• 4、类结束生命周期有几种方式:
1. 程序正常执行结束。
2. 程序执行过程遇到异常
3. 系统出现错误,导致JVM异常终止掉。
4. 在程序里执行了SYSTEM.EXIT方法。
二、类加载器
• 1、一旦一个类被加载到JVM中,同一个类就不会被载入了。
这里同一个类是指:一个类用 限定类名 作为标识。
在jvm中,一个类用 限定类名 和其 类加载器 作为唯一标识。
(限定类名,就是类名全称,带包路径的用点隔开,例如: java.lang.String。)
• 2、类加载器的种类(4种)
启动/扩展/系统/用户。
启动类加载器: 负责加载JRE核心类库,如JRE目标下的rt.jar charsets.jar等
扩展类加载器: 负责加载JRE扩展目录ext中jar类包。
系统类加载器: 负责加载ClassPath路径下的类包。(大多数类使用这个)
用户自定义加载器:负责加载用户自定义路径下的类包。
• 3、类加载机制:
1. 全盘负责:当加载这个类的时候,若这个类是在别的类里的,那么就委托给了调用者的这个类去进行加载。(除非自己指定选用某类进行加载时,才会特例。)
2. 父类委托(双亲委派机制):尝试让父类加载器加载,当父类加载器无法加载时才让从自己的类路径中加载。
优势:
沙箱安全机制:比如自己写的String.class类不会被加载,这样可以防止核心库被随意篡改
避免类的重复加载:当父ClassLoader已经加载了该类的时候,就不需要子ClassLoader再加载一次。
3. 缓存机制:所有加载过的Class都会被缓存。