类加载过程

加载->链接(验证,准备,解析)->初始化

1.加载:

利用io从文件系统中读取.class文件,通过类加载器(classLoader)进字节码加载到计算机内存中供Jvm使用。

 

java的四种类加载器(父加载器->子加载器)

1引导类加载器:加载Java 的核心库

2扩展类加载器:加载java 的扩展库

3系统类加载器:加载Java 应用的类路径(CLASSPATH) 自定义的类通过系统类加载器或自定义类加载器加载

4自定义类加载器:开发人员自定义java类加载器

 

 

 

怎么确定使用哪种加载器来加载一个类?

java体系中使用的加载机制是双亲委派模式:

大致流程:加载器如果还有父加载器就将加载交到父加载器加载。

其实真正的加载过程是从1引导类加载器开始加载,加载不了则继续先下加载。

 

优点:

1.防止一个类重复加载

2.保证java核心API不会被修改

即使外部重新定义了java核心库的类(比如Object),但是仍然会被引导类加载器加载而不是系统类加载器加载。

 

思考:为什么不直接从引导类加载器开始加载?

 

2.链接:

2.1.1验证

这里验证的就是后缀名是.class文件,因为我也可以把随便一个其他后缀名(比如.txt .exe)修改成.class文件

验证阶段可以检验是否是合法的class文件,是否有必要加载到内存中

魔数:cafe babe

2.1.2准备

为类中的所有静态变量分配内存空间,并为其设置一个初始值

被final修饰的静态变量,会直接赋予原值

2.1.3解析

 所谓解析就是指在常量池(jdk1.8从方法区转移到堆中,方法区更改成元空间)中找到类、接口、方法、字段的符号引用(代码),并将其替换为直接引用(具体指针)的过程。

 

 

3.初始化:

这里执行的是cinit方法,不是执行构造函数方法。

执行所有static方法的代码,将准备阶段static变量进行赋值。

 

补充一点:

加载阶段优先于链接阶段,但是加载的过程,链接阶段也在进行。

是一个并发的过程。

链接过程在加载过程之后结束。

 

再补充一点:

当一个类在初始化时,要求其父类全部都已经初始化过了

但是在一个接口初始化时,并不要求父接口完全完成了初始化,只有在真正使用到父接口的时候才会初始化(如引用接口中定义的常量。