面试题--JAVA中静态块、静态变量加载顺序

最后给大家一道面试题练练手,要求写出其结果(笔试)

 

[java] view plain copy
 
  1. public class StaticTest {  
  2.       
  3.     public static int k = 0;  
  4.     public static StaticTest t1 = new StaticTest("t1");    
  5. 代码执行完这一行发生了什么?之所以会执行这行代码,是main方法里面第一次 new的缘故,第一次new,会加载这个类的static变量,static方法(不执行)和static块,因为 t1 是static,所以会执行这一行代码  但 t1 这里又new了一个StaticTest对象,由于在main方法里面已经new了一个,所以这里new的不再加载static变量和块,只初始化变量j,加载构造快和构造函数,在加载 j 时,又需要用到static变量 i 和 n ,但此时并未给 i 和 n 初始化(因为还没有执行到给 i 和 n 初始化的代码),所以此时的 i 和 n 用默认值 0 !  我去。。。。
  6. 当代吗执行到这时,jvm如何知道这已经是第二次new了?因为类加载过程中存在一个准备阶段,这个阶段是在方法区中为所有类变量赋初值(除了static final是直接赋了指定值);然后才到了类初始化阶段,这里执行到new实际上是到了类初始化阶段,这时方法区已经有了这个类的信息了,所以jvm才知道这不是第一次new;

注:main方法所在类,是被隐式初始化了,但没有被实例化

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


结果:

 

 

[java] view plain copy
 
  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.加载的顺序:先父类的static成员变量 -> 子类的static成员变量 -> 父类的成员变量 -> 父类构造 -> 子类成员变量 -> 子类构造

2.static只会加载一次,所以通俗点讲第一次new的时候,所有的static都先会被全部载入(以后再有new都会忽略),进行默认初始化。在从上往下进行显示初始化。这里静态代码块和静态成员变量没有先后之分,谁在上,谁就先初始化

3.构造代码块是什么?把所有构造方法中相同的内容抽取出来,定义到构造代码块中,将来在调用构造方法的时候,会去自动调用构造代码块。构造代码快优先于构造方法。

posted on 2018-03-07 14:33  吉晨  阅读(1874)  评论(0编辑  收藏  举报

导航