【2021-06-30】分析程序的运行结果,并解释为什么?
请移步至:
每日一题 查看更多的题目 ~
题目链接:【2021-06-30】分析程序的运行结果,并解释为什么?
第一题的答案为:
myTestClass.a : 0
myTestClass.b : 1
本题考查的知识点为类加载的顺序,类从被加载至 JVM 到卸载出内存整个生命周期为:
各个阶段的主要功能:
加载:查找并加载类文件的二进制数据
连接:将已经读入内存的类的二进制数据合并到 JVM 运行时环境中去,包含如下几个步骤:
验证:确保被加载类的正确性
准备:为类的静态变量分配内存,赋默认值;例如:
public static int a = 1;
在准备阶段对静态变量 a 赋默认值 0解析:把常量池中的符号引用转换成直接引用
初始化:为类的静态变量赋初始值,这个时候才对静态变量 a 赋初始值 1
我们可以看到,Java 中,类的静态成员在类加载时就已经被加载到内存中了!
就本题,我们来分析下类加载的过程:
首先在连接的准备阶段,JVM 会为类的静态变量分配内存,并赋缺省值,即:
myTestClass = null;
a = 0;
b = 0;
接着,在类的初始化阶段,会为这些静态变量赋初始值
这句话会回调构造器
让a++;b++;
导致 a 和 b 的结果均为 1
然后代码执行到:
a = 0;
b;
这个时候,执行对 a 和 b 真正的初始化赋值
又将 a 变为了 0 ;而 b 则没有赋值结果仍然是 1;所以输出结果为
myTestClass.a : 0
myTestClass.b : 1
第二题的结果为:
myTestClass2.a : 1
myTestClass2.b : 1
我们再次按照类的初始化顺序进行分析:
首先在连接的准备阶段,JVM 会为类的静态变量分配内存,并赋缺省值,即:
a = 0;
b = 0;
myTestClass2 = null;
然后,在类的初始化阶段,会为这些静态变量赋初始值
首先,代码执行到:
a = 0;
b;
a 赋初始值为 0,然后 b 没有赋值,其结果还是 0
接着,执行到语句:
myTestClass = new MyTestClass();
这句话会回调构造器
private MyTestClass() {
a++;
b++;
}
执行 a++;b++;
,导致 a 和 b 的结果均为 1,所以最终程序输出的结果为:
myTestClass2.a : 1
myTestClass2.b : 1