类的初始化
1.什么是类的初始化
JVM执行类的初始化语句,为类的静态变量赋值。
- 如果这个类还没有被加载和链接,那就先进行加载和链接
- 如果这个类存在父类,且为被初始化,先对其父类进行初始化
- 如果这个类存在初始化语句(static块),依次执行初始化语句
2.类的初始化顺序
- 父类的静态变量和static代码块
- 子类的静态变量和static代码块
- 父类的普通成员变量和非static代码块
- 父类构造函数
- 子类的普通成员变量和非static代码块
- 子类构造函数
我们可以通过代码验证下这个顺序:
- 定义父类Person和子类Student
/**
* 父类
*/
public class Person {
public static String name = "姓名";
public String age = "40";
static {
System.out.println("父类静态变量初始化==>"+name);
System.out.println("父类静态代码块初始化");
}
{
System.out.println("父类非静态变量初始化==>"+age);
System.out.println("父类非静态代码块初始化");
}
public Person(){
System.out.println("父类构造器初始化");
}
}
class Student extends Person {
public static String name = "张三";
public String age = "18";
static {
System.out.println("子类静态变量初始化==>"+name);
System.out.println("子类静态代码块初始化");
}
{
System.out.println("子类非静态变量初始化==>"+age);
System.out.println("子类非静态代码块初始化");
}
public Student(){
System.out.println("子类构造器初始化");
}
public static void main(String[] args) {
new Student();
}
}
- 执行代码
public static void main(String[] args) {
new Student();
}
- 查看执行结果
父类静态变量初始化==>姓名
父类静态代码块初始化
子类静态变量初始化==>张三
子类静态代码块初始化
父类非静态变量初始化==>40
父类非静态代码块初始化
父类构造器初始化
子类非静态变量初始化==>18
子类非静态代码块初始化
子类构造器初始化
3.什么时候会进行类的初始化?
- 创建类的实例 eg:new Student() || Class.newInstance() || constructor.newInstance()
- 访问某个类的静态变量,或者对静态变量进行赋值
- 调用类的静态方法
- Class.forName("")
底层实质上是调用一个forName0的方法,会传三个参数,其中init参数默认为true
@CallerSensitive public static Class<?> forName(String className) throws ClassNotFoundException { Class<?> caller = Reflection.getCallerClass(); return forName0(className, true, ClassLoader.getClassLoader(caller), caller); } - 子类初始化时,也会完成对本类的初始化(接口除外)
子类初始化时,如果父类未进行初始化,会先初始化其父类
- 该类是程序引导入口(main方法入口或者test方法入口)

浙公网安备 33010602011771号