1.什么是类加载
类加载子系统只是负责加载class字节码文件将类信息放至方法区中,至于是否可以运行,是执行引擎负责的事情。
2.类加载的过程
2.1加载
-
IO读取字节码文件
-
为每个类创建一个Class类的对象
-
将此对象存储在方法区中
2.2链接
2.2.1验证
验证文件的格式是否相同,看文件是否被污染,class文件都有固定的开头表示序列。
2.2.2准备
为类的静态变量分配内存,并且设置初始值为0;例如:
public static int value = 123; value在准备阶段后的初始值是 0,而不是 123.
注意:静态常量(final修饰并且已经指定字面量)是在编译时进行赋值了的。如下:
public final static int value = 5;
2.2.3解析
将class文件中的二进制数据的符号引用替换为直接引用。
2.3初始化
将类中的静态变量进行初始化。例如:
public static int value = 123; value在初始化之后为123.
静态(static修饰)的语句初始化的顺序,先父类static——>后子类static,由上到下依次进行:
3.类什么时候会被初始化(即类加载完成)?
JVM规定,每个类被首次主动使用时才会对其进行初始化。例如:
-
new关键字创建对象
-
访问类的静态变量,方法
-
class.forName("类地址"),通过反射
-
执行该类的main方法
-
初始话子类会先导致其父类的初始化
两种被动使用情况下不会初始化该类。如下:
-
应用该类的已经指定了字面量的静态常量,不会导致该类的初始化,因为是在编译期间就初始化赋值了的,但是对于静态常量还有特殊情况,需要计算出来的结果才能初始化,如下:
public final static int RANDOM = new Random().nextInt(); //会导致类加载
-
构造每个类的数组时不会导致该类初始化,例如:
Student[] students = new Student[10];