zoukankan      html  css  js  c++  java
  • 面试题--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.构造代码块是什么?把所有构造方法中相同的内容抽取出来,定义到构造代码块中,将来在调用构造方法的时候,会去自动调用构造代码块。构造代码快优先于构造方法。

  • 相关阅读:
    [板子]用线段树解决ST表问题
    [POJ2528]Mayor's posters(离散化+线段树)
    [板子]Kruskal
    [板子]segTree
    js实现工具函数中groupBy数据分组
    关于爬虫
    jsencrypt vue相关的rsa加密
    less 循环模拟sass的for循环效果
    vue 自动生成菜单
    vue中form 表单常用校验封装(async-validator)
  • 原文地址:https://www.cnblogs.com/jichen/p/8522205.html
Copyright © 2011-2022 走看看