杭州某互联网公司校招笔试Java选做题

来源:互联网 发布:数据库添加字段 编辑:程序博客网 时间:2024/04/29 22:17

请给出下面代码的输出:

public class Test1 {/** * @param args */public static int k=0;public static Test1 t1=new Test1("t1");public static Test1 t2=new Test1("t2");public static int i=print("i");public static int n=99;public int j=print("j");{print("构造块");}static {print("静态块");}public Test1(String str) {System.out.println((++k)+":"+str+"\t i="+i+"\t n="+n);++i;++n;}public static int print(String str) {System.out.println((++k)+":"+str+"\t i="+i+"\t n="+n);++n;return ++i;}public static void main(String[] args) {Test1 t=new Test1("init");}}


初看时,感觉略显棘手,主要卡在

public static Test1 t1=new Test1("t1");public static Test1 t2=new Test1("t2");

调用main方法,首先会加载Test1类。类加载过程分为:加载、连接、初始化三部分,其中连接又分为:验证、准备、解析。关于虚拟机类加载机制 Java虚拟机会在准备阶段为类Field赋默认初始值,在初始化阶段才会执行初始化语句和静态初始化块。因此在初始化阶段开始之前,各类Field值为:

public static int k=0;public static Test1 t1=null;public static Test1 t2=null;public static int i=0;public static int n=0;

问题是,在类初始化阶段,执行到

public static Test1 t1=new Test1("t1");

怎么办?当时搞不懂的地方是:实例化对象之前,如果类还没加载完怎么办?运行的结果是:如果在类加载过程中遇到实例化对象的语句,则去实例化对象。(至于原理,还待解,期待高手的解答!)即在执行这条语句的时候会转而去执行类Test1的构造器,在执行构造器时发现还有一个实例Field j 和一个普通初始化没有初始化,于是再转而去初始化实例Field j和普通初始化块。j的初始化由print("j")的返回值来完成,因此此时将输出:


1:j i=0 n=0


j被初始化为1,同时k=1, n=1, i=1;

在执行完实例Field j的初始化工作之后,接着要执行普通初始化块

{print("构造块");}

的初始化,此时输出:

2:构造块 i=1 n=1


同时 k=2, n=2, i=2;

执行完实例Field和普通初始化块之后就可以开始执行构造器了,此时输出:

3:t1 i=2 n=2


同时 k=3, n=3, i=3;

到此为止,Test1的实例 t1的创建完成。类似的,t2的创建如t1。依次输出:


4:j i=3 n=3
5:构造块 i=4 n=4
6:t2 i=5 n=5


此时,k=6, n=6, i=6;
接着初始化类Field i,执行print("i");此时输出:


7:i i=6 n=6


此时,k=7, n=7, i=7;

然后将n初始化为99。

此时所有的类Field都已初始化完毕。最后执行静态初始化块

static {print("静态块");}

此时输出:

8:静态块 i=7 n=99


至此,完成了类Test1的类加载过程。

最后执行main方法中Test1的实例 t 的创建,此过程与t1、t2类似。输出:


9:j i=8 n=100
10:构造块 i=9 n=101
11:init i=10 n=102


因此,程序最终输出结果:


1:j i=0 n=0
2:构造块 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:构造块 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:静态块 i=7 n=99
9:j i=8 n=100
10:构造块 i=9 n=101
11:init i=10 n=102



原创粉丝点击