java中代码的加载顺序所能了解的知识点
类的依赖关系
static代码块的加载时间
继承类中构造器的隐式调用
非static的成员变量初始化时间
main方法和static的加载顺序
测试代码如下:
public class app { private static app d = new app(); private subclass t = new subclass(); static{ system.out.println("app static");//6 } public app(){ system.out.println("构建app");//5 } public static void main(string[] args) { system.out.println("app main");//7 } } //父类 class superclass{ static{ system.out.println("superclass static");//1 } superclass(){ system.out.println("构建superclass");//3 } } //子类 class subclass extends superclass{ static{ system.out.println("subclass static");//2 } public subclass(){ //super() system.out.println("构建subclass");//4 } }
输出结果
superclass static subclass static 构建superclass 构建subclass 构建app app static app main
分析
因为在app类中,声明了subclass的变量,所以jvm先加载subclass类,不然无法编译app。
subclass是superclass的子类,在继承关系的类中,父类先加载进jvm,不然子类无法编译。
在类中static代码会在字节码文件加载进jvm的时候调用一次,且在该类的生命周期中只会调用一次。所以在第一行输出的是superclass static,随后subclass加载进了jvm,输出第二行的subclass static
声明的static成员变量,其初始化是在static代码块中。非static成员变量,其初始化是在构造器中,且是在构造器的代码前面。
创建静态的成员变量d之前会先创建成员变量t,在subclass的构造器中会隐式的使用super()调父类的构造器,所以第三行输出构建superclass,第四行输出subclass。
在app的构造器中创建好了成员变量t后,向下执行,输出第五行的构建app
。
随后继续执行app的静态代码块(因为d是static的变量,所以并不是说app的构造器比static先执行),输出第六行的app static
。
最后执行public类的入口方法main,输出第七行的app main
。
希望本篇文章对您有所帮助
如对本文有疑问, 点击进行留言回复!!
Springboot项目因为kackson版本问题启动报错解决方案
Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解
网友评论