类的初始化
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方法入口)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)