Java 类初始化顺序 -- 结合阿里2014校招笔试 Java 附加题

来源:互联网 发布:淘宝店铺红包怎么领取 编辑:程序博客网 时间:2024/04/28 11:14

 

首先用文字简单描述一下Java 类的初始化顺序(此处引用 Core Java Volume I 中的译文)


规则1在类第一次加载的时候,将会进行静态域的初始化:

1. 将所有的静态数据域初始化为默认值(0、false 和 null)

2. 按照在类中定义的顺序依次执行静态初始化语句和静态初始化块


规则2:调用构造器的具体处理步骤:

1. 所有的数据域初始化为默认值(0、false 和 null)

2. 按照在类中定义的顺序依次执行初始化语句和初始化块

3. 如果构造器调用的其他的构造器,则转而执行另一构造器

4. 执行构造器主体


类加载的时机只需简单的知道是在调用构造器之前且只有一次,具体的类加载过程这里就不说了,否则就跑得太偏了。


下面我们来看一下阿里巴巴 2014 年校招研发类笔试的 Java 附加题

[java] view plaincopyprint?
  1. public class Test {  
  2.   
  3.     public static int k = 0;  
  4.     public static Test t1 = new Test("t1");  
  5.     public static Test t2 = new Test("t2");  
  6.     public static int i = print("i");  
  7.     public static int n = 99;  
  8.     private int a = 0;  
  9.     public int j = print("j");  
  10.     {  
  11.         print("构造块");  
  12.     }  
  13.     static {  
  14.         print("静态块");  
  15.     }  
  16.   
  17.     public Test(String str) {  
  18.         System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);  
  19.         ++i;  
  20.         ++n;  
  21.     }  
  22.   
  23.     public static int print(String str) {  
  24.         System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);  
  25.         ++n;  
  26.         return ++i;  
  27.     }  
  28.   
  29.     public static void main(String args[]) {  
  30.         Test t = new Test("init");  
  31.     }  
  32.   
  33. }  

这里的输出结果为:

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

我当时看到这个题目的时候,心里直接两个字:我草...

其实仔细分析一下,用到的东西不过就是上面咱们说的那些规则。



以下为详细分析:

1. 首先类被加载,类中所有的静态域被初始化为0、false 或 null(注意这里并没有执行初始化语句,千万要搞明白初始化语句这里的区别)。

    变量状态:k, i, n = 0; t1, t2 = null

2. 然后依照定义次序执行类中的静态域初始化语句和静态初始化块

3. 执行到静态初始化语句 public static Test t1 = new Test("t1"); 时,调用构造器(这里类不会再次加载),这是会产生一个新对象 t1,对新对象执行上面说的步骤1。

4. 对象 t1 初始化输出为:

[plain] view plaincopyprint?
  1. 1:j   i=0    n=0  
  2. 2:构造块   i=1    n=1  
  3. 3:t1   i=2    n=2  
5. 对象 t1 构造完毕后,接下来构造 t2,过程和上面相同,这一步骤的输出为:

[plain] view plaincopyprint?
  1. 4:j   i=3    n=3  
  2. 5:构造块   i=4    n=4  
  3. 6:t2   i=5    n=5  
6. 然后执行 public static int i = print("i"); 和静态初始化块,输出:

[plain] view plaincopyprint?
  1. 7:i   i=6    n=6  
  2. 8:静态块   i=7    n=99  
7. 至此,类加载完毕,接下来便是 main 函数中的对象 t 的构造,构造过程为步骤 1。输出为:

[plain] view plaincopyprint?
  1. 9:j   i=8    n=100  
  2. 10:构造块   i=9    n=101  
  3. 11:init   i=10    n=102  

 

 

 

 

 

 

 

 

转自:http://blog.csdn.net/geekdonie/article/details/12260599

 

 

 

 


0 0
原创粉丝点击