原文:https://blog.csdn.net/sunroyfcb/article/details/81637565
最近在总结一些和JVM相关的知识,现在总结一下关于父类和子类加载顺序的问题。简而言之就是先静态后非静态,先父类后子类,具体顺序如下:
- 父类静态变量
- 父类静态代码块(若有多个按代码先后顺序执行)
- 子类静态变量
- 子类静态代码块(若有多个按代码先后顺序执行)
- 父类非静态变量
- 父类非静态代码块(若有多个按代码先后顺序执行)
- 父类构造函数
- 子类非静态变量
- 子类非静态代码块(若有多个按代码先后顺序执行)
- 子类构造函数
所有的静态资源都只会加载一次,非静态资源可以重复加载。
个人笔记:
1.多个静态代码块,在编译时会按照书写顺序整合到一个静态代码块,而且该静态代码块在类加载时执行(加载到方法区中),是最先执行的。
2.多个非静态代码块(又称构造代码块),在编译时会按照书写顺序整合成一个非静态代码块,接着嵌套到每一个构造器的开头。
3.存在继承的情况时,先加载父类再加载子类,所以父类的静态代码块先执行,再到子类的静态代码块,接着创建对象时,先调用父类的构造器(编译后已经嵌套了非静态代码块)再调用子类的构造器,所以父类的非静态代码块先执行,再到父类的构造器,接着到子类的非静态代码块,最后到子类的构造器。
例:
public class Block {
static {
System.out.println("这是一个静态代码块");
}
{
System.out.println("这是一个非静态代码块");
}
static {
System.out.println("这是二个静态代码块");
}
{
System.out.println("这是二个非静态代码块");
}
public Block(){
System.out.println("构造器中代码");
}
public static void main(String[] args) {
new Block();
}
}
反编译上面代码如下:
public class Block {
static {
System.out.println("这是一个静态代码块");
System.out.println("这是二个静态代码块");
}
public Block() {
System.out.println("这是一个非静态代码块");
System.out.println("这是二个非静态代码块");
System.out.println("构造器中代码");
}
public static void main(String[] args) {
new Block();
}
}
运行结果:
最近在总结一些和JVM相关的知识,现在总结一下关于父类和子类加载顺序的问题。简而言之就是先静态后非静态,先父类后子类,具体顺序如下: