java类的加载顺序,静态块 非静态块 构造器、属性、方法等
先看最终结论:
1、父类静态变量和静态代码块(先声明的先执行);
2、子类静态变量和静态代码块(先声明的先执行);
3、父类的变量和代码块(先声明的先执行);
4、父类的构造函数;
5、子类的变量和代码块(先声明的先执行);
6、子类的构造函数。
第1次测试
三个类如下
public class Parent {
static String parentStaticValue = "parentStaticValue";
String parentValue = "parentValue";
Parent() {
System.out.println("parent constructor");
}
static {
System.out.println("parent static block");
}
{
System.out.println("parent block");
}
static void parentStaticMethod() {
System.out.println("parentStaticMethod");
}
void parentMethod() {
System.out.println("parentMethod");
}
}
public class Child extends Parent {
static String childStaticValue = "childStaticValue";
String childValue = "childValue";
public Child() {
System.out.println("child constructor");
}
static {
System.out.println("child static block");
}
{
System.out.println("child block");
}
static void childStaticMethod() {
System.out.println("childStaticMethod");
}
void childMethod() {
System.out.println("childMethod");
}
}
public class ChildTest {
public static void main(String[] args) {
System.out.println("第1次 new Child()");
new Child();
System.out.println("第2次 new Child()");
new Child();
}
}
运行Test类输入结果
结论1
父类的静态代码块 —> 子类静态静态代码块 —> 父类非静态代码块 —> 父类构造器 —> 子类非静态代码块 —> 子类构造器
但是上面的测试不能类的属性和类的代码块加载顺序
第2次测试
package top.lishuoboy.java_basic.class_load_order;
public class Parent2 {
static String parentStaticValue1 = "parentStaticValue1";
static {
System.out.println("parent static block1");
}
static String parentStaticValue2 = "parentStaticValue2";
Parent2() {
System.out.println("parent constructor");
}
}
public class Parent2Test {
public static void main(String[] args) {
new Parent2Test();
}
}
打断点执行Parent2Test,看输出结果
再看一下图,编译不通过,提示非法的引用
继续修改代码
public class Parent3 {
static {
System.out.println("parent static block1");
run();
}
static String parentStaticValue = "parentStaticValue";
static {
System.out.println("parent static block2");
run();
}
static void run() {
System.out.println(parentStaticValue);
}
Parent3() {
System.out.println("parent constructor");
}
}
public class Parent3Test {
public static void main(String[] args) {
new Parent3Test();
}
}
输出结果(与run方法的书写顺序无关)
结论2
静态块和静态属性代码按代码书写顺序加载。非静态也一样,不再代码演示。结论如下:
(静态)变量和(静态)代码块的也是有执行顺序的,与代码书写的顺序一致。在(静态)代码块中可以使用(静态)变量,但是被使用的(静态)变量必须在(静态)代码块前面声明
最终结论:
1、父类静态变量和静态代码块(先声明的先执行);
2、子类静态变量和静态代码块(先声明的先执行);
3、父类的变量和代码块(先声明的先执行);
4、父类的构造函数;
5、子类的变量和代码块(先声明的先执行);
6、子类的构造函数。
那么类的方法什么时候加载呢?
补充
1、修改Test,调用子类的父类的静态属性
public class Test {
public static void main(String[] args) {
System.out.println("第1次 Child.parentStaticValue");
String a = Child.parentStaticValue;
System.out.println("第2次 Child.parentStaticValue");
String b = Child.parentStaticValue;
}
}
输出结果
2 、修改Test,调用子类的静态属性
public class Test {
public static void main(String[] args) {
System.out.println("第1次 Child.childStaticValue");
String a = Child.childStaticValue;
System.out.println("第2次 Child.childStaticValue");
String b = Child.childStaticValue;
}
}
输出结果
结论,自己看吧
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具