Java父类子类加载顺序
父类如下:
package zzm.java.extendsDemo; public class Parent { /** * 会报错,因为static按顺序进行加载的 */ // static { // System.out.println("i="+i); // } public static int i = 0; { i++; System.out.println("i(非静态)="+i); } static { i = i+1; System.out.println("i(静态)="+i); } { i++; System.out.println("i(非静态)="+i); } public Parent(){ i++; System.out.println("i(构造方法)="+i); } }
子类如下:
package zzm.java.extendsDemo; public class Child extends Parent{ public static int i = 0; { i++; System.out.println("i(子类非静态)="+i); } static { i = i+1; System.out.println("i(子类静态)="+i); } { i++; System.out.println("i(子类非静态)="+i); } public Child(){ //显示调用父类构造方法,必须放在最前面,和不写是一样的 super(); i++; System.out.println("i(子类构造方法)="+i); } public static void main(String[] args) { Child child1 = new Child(); Child child2 = new Child(); } }
猜猜输出是啥?
下面是打印
i(静态)=1 i(子类静态)=1 i(非静态)=2 i(非静态)=3 i(构造方法)=4 i(子类非静态)=2 i(子类非静态)=3 i(子类构造方法)=4 i(非静态)=5 i(非静态)=6 i(构造方法)=7 i(子类非静态)=5 i(子类非静态)=6 i(子类构造方法)=7
由此我们得出下面几个结论:
1、先执行父类的静态变量、静态方法块,谁在前面谁先执行
2、在执行子类的静态变量、静态方法块,也是一样,谁在前面谁先执行
3、在执行父类的非静态变量、非静态方法块,接着执行对应子类
4、最后在执行父类构造方法、在执行子类构造方法
5、当类已经被加载后,第二次加载时不会在执行静态变量的赋值,已经静态方法块,但是会执行非静态变量的赋值和非静态方法块。
因为一个静态变量的初始化是在类加载的准备阶段,这个阶段会执行静态变量的赋值以及相关的静态代码块,是<client>()方法执行的,执行时机是类加载的时候
而非静态方法,是由<init>()方法执行的,执行时间是构造实例的时候,随着实例化时一起放在堆上
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理