JAVA代码执行顺序解析

今天的博客记录一道题目,求出以下代码,所打印出的顺序,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class App
{
private static App d = new App();
private SubClass t = new SubClass();
static
{
System.out.println(3);
}
public App()
{
System.out.println(4);
}
public static void main(String[] args)
{
System.out.println("Hello World!");
}

}
class SuperClass
{
SuperClass()
{
System.out.println("SuperClass 构造器");
}
}
class SubClass extends SuperClass
{
static
{
System.out.println(1);
}
public SubClass()
{
System.out.println(2);
}
}

此题主要考察构造器,类及静态变量、非静态变量,父类,子类在JVM中的调用顺序。
答案在我第一次做的时候确实是意想不到:

1
2
3
4
5
6
1
SuperClass 构造器
2
4
3
Hello World!

JVM代码块加载原则

1.优先加载主类以外,与主类相关的其他类,方便主类进行调用。
2.如果代码块有static修饰,则优先加载进JVM进行执行。
3.子类中的构造器自带一个super();方法,且在构造器的第一行代码中,因此当父类的构造器为无参数构造器时,子类将优先调用父类的无参数构造器的内容。

题目中的加载顺序分析

1.第一个为什么是1,因为主类中的main方法会在其他相关的父类和子类优先调用之后,再进行调用,因此优先进行调用SuperClass和SubClass,在这两个类中,SubClass又是SuperClass的子类,理论上应先行调用父类,但子类中包含静态代码块,因此优先调用static修饰的静态字码快中的内容,从而优先输出“1”;
2.为什么第二个是“SuperClass 构造器”,上面优先打印1的原理讲明白了,第二个也就好理解了,子代码块中的构造器自带一个super();的方法,会优先进行调用父类中的无变量构造器。因此打印出“SuperClass 构造器”。
3.为什么第三个是数字2,构造器的运行顺序是自顶向下的,因此执行完super();后,就开始执行下一字段,也就是2;
4.为什么第四个是数字4?非主类中的其他类已经加载完毕,那么现在开始加载主类,主类中又有一个static修饰的代码块,因此主类优先执行了App();中的打印4,操作
5.同样,根据自顶向下原色,执行了打印3的操作。
6.也就是最后,打印了main方法中的“Hello World!”。

文章目录
  1. 1. JVM代码块加载原则
  2. 2. 题目中的加载顺序分析
|