构造方法之初始化块的加载时机

    首先说明类在什么情况下被装在到系统中:

1、当用户访问该类的静态成员变量或调用该类的静态方法时,尽管没有使用类创建对象,但是该类将被装入系统。

2、当用户使用new关键字创建一个类的对象时,该类被装入系统。

    第二需要了解java中初始化数据域的方法包括:

1、在构造方法中赋值;

2、在声明中赋值;

3、创建初始化块。初始化块又分为静态初始化块和初始化块(格式见下图)。静态初始化块在类第一个被加载的时候调用,仅调用一次,初始化块可多次调用。

        初始化的顺序从下面的执行顺序可以看出,首先执行静态初始化块,然后初始化块,最后才是构造方法。静态初始化块仅执行一次。



在某公司面试时碰见的该题目,

[java]  view plain  copy
  1. package com.skd.timu;  
  2.   
  3. public class Demo4 {  
  4.     public static void main(String[] args) {  
  5.         new childrenDemo();  
  6.         new childrenDemo();  
  7.     }  
  8. }  
  9.   
  10. class ParentDemo{  
  11.      static String staParentString="父类-静态-变量";  
  12.      String parentString="父类-非静态-变量";  
  13.       
  14.      static{  
  15.          System.out.println(staParentString);  
  16.          System.out.println("父类 -  静态 - 初始化块");  
  17.      }  
  18.      {  
  19.          System.out.println(parentString);  
  20.          System.out.println("父类 - 非静态 - 初始化块");  
  21.      }  
  22.      ParentDemo(){  
  23.          System.out.println("父类-构造方法");  
  24.      }  
  25. }  
  26.   
  27. class  childrenDemo extends ParentDemo{  
  28.     static  String staChildrenString="子类-静态-变量";  
  29.      String childrenString="子类-非静态-变量";  
  30.       
  31.      static{  
  32.          System.out.println(staChildrenString);  
  33.          System.out.println("子类 -  静态 - 初始化块");  
  34.      }  
  35.      {  
  36.          System.out.println(childrenString);  
  37.          System.out.println("子类- 非静态 - 初始化块");  
  38.      }  
  39.      childrenDemo(){  
  40.          System.out.println("子类-构造方法");  
  41.      }  

先把程序执行的结果贴上:

[java]  view plain  copy
  1. 父类-静态-变量  
  2. 父类 -  静态 - 初始化块  
  3. 子类-静态-变量  
  4. 子类 -  静态 - 初始化块  
  5. 父类-非静态-变量  
  6. 父类 - 非静态 - 初始化块  
  7. 父类-构造方法  
  8. 子类-非静态-变量  
  9. 子类- 非静态 - 初始化块  
  10. 子类-构造方法  
  11. 父类-非静态-变量  
  12. 父类 - 非静态 - 初始化块  
  13. 父类-构造方法  
  14. 子类-非静态-变量  
  15. 子类- 非静态 - 初始化块  
  16. 子类-构造方法  

顺序为:

1、父类静态变量——父类静态非初始化块——子类静态变量——子类静态初始化块

2、父类非静态变量——父类初始化块——父类构造方法——子类非静态变量——子类初始化块——子类构造方法

总结为:父类和子类的静态变量和静态初始化块最先执行,变量都优先于初始化块执行。



从输出结果可以看出,静态变量和静态初始化块只在程序加载的时候执行一次,执行次序在最前面,是全局的;

构造块的加载顺序在静态块之后但在构造方法之前,而且在构造块加载之前,变量已经加载;

构造方法是在静态变量,静态块,变量,构造块后才加载的,是在类实例化时,除了调用方法外的最后加载的位置;

因为静态变量和静态块都是全局的,因此在程序加载时就已经加载,不会因为是子类中的静态变量和静态块就比父类的构造块加载晚,但在都是静态变量或静态块的情况下,

总是先初始化父类的,然后初始化子类的。

同样的因为构造块和构造方法不是全局的,而且子类在实例化时总是先调用父类的构造块和构造方法,因此父类的构造块和构造方法在子类的之前调用。即在实例化子类时,程序会先调用父类的实例化构造块或者构造方法,然后才会调用子类的构造块和构造方法完成子类的实例化。

而且,构造块和构造方法会在每次实例化的时候都执行,静态变量和静态块只会执行一次(不管该类实例化多少对象)。


猜你喜欢

转载自blog.csdn.net/qq_39008429/article/details/80431454