zoukankan      html  css  js  c++  java
  • 浅谈对象的初始化顺序

    1.没有继承情况下的初始化顺序

     1 package InitializationOrder;
     2 /**
     3  * 没有继承的初始化顺序
     4  * @author TANJIAYI
     5  *
     6  */
     7 public class Test4 {
     8     public static void main(String[] args) {
     9         new Order();
    10     }
    11 }
    12 class Order{
    13     AAA s = new AAA("成员变量");
    14     static AAA a = new AAA("静态成员变量");
    15     {
    16         System.out.println("初始化块");
    17     }
    18     static{
    19         System.out.println("静态初始化块");
    20     }
    21      Order(){
    22         System.out.println("构造方法");
    23     }
    24     
    25 }
    26 class AAA{
    27     public AAA(String str){
    28         System.out.println(str);
    29     }
    30 }

      输出结果:

    静态成员变量

    静态初始化块

    成员变量

    初始化块

    构造方法      

    结论:在没有继承的条件下,实例化一个对象,构造的先后顺序是,静态成员变量>静态初始化块>成员变量>初始化块>构造方法

    一般顺序为 先静态,后非静态,先变量,后初始化块,再是构造方法

    2.经典面试题

    直接上代码:

     1 package InitializationOrder;
     2 /**
     3  * 初始化顺序  静态变量  静态初始化块  成员变量 初始化块  构造函数
     4  * @author TANJIAYI
     5  *
     6  */
     7 public class Test1 {
     8     
     9         public static Test1 t1 = new Test1("t1");//第1步    
    10         public static int k = 0;
    11         public static Test1 t2 = new Test1("t2");//第2步
    12         public static int i = print("i");//第3步
    13         public static int n = 99;//第4步
    14         public int j = print("j");//第6步
    15                 {
    16                     print("构造");//第7步
    17                 }
    18                 static{
    19                     print("静态");//第5步
    20                 }
    21         public Test1(String str){
    22             System.out.println((++k)+":"+str+"  i="+i+" n="+n);
    23             ++i;
    24             ++n;
    25         }
    26         private static int print(String str) {
    27             System.out.println((++k)+":"+str+"  i="+i+" n="+n);//1:j i=0 n=0
    28             ++n;
    29             return ++i;
    30         }
    31         public static void main(String[] args) {
    32             Test1 test = new Test1("init");//第8步
    33         }
    34 }

    输出结果为:

    1:j  i=0 n=0

    2:构造  i=1 n=1

    3:t1  i=2 n=2

    1:j  i=3 n=3

    2:构造  i=4 n=4

    3:t2  i=5 n=5

    4:i  i=6 n=6

    5:静态  i=7 n=99

    6:j  i=8 n=100

    7:构造  i=9 n=101

    8:init  i=10 n=102

    解题思路:

    (1)   按照对象初始化顺序依次执行,首先静态变量从代码中的第九行到第13行依次执行。

    (2)   执行第1步,调用new Test1()方法,本方法是个构造方法,在执行前,类加载的时候先把k,i和n的值加载进来,初始值为0,接着执行第14行成员变量j;调用print()方法,把j赋给str,所以27行代码打印第一条输出:1:j i=0 n=0,在执行初始化块,15—17行,打印出2:构造 i=1 n=1,最后在执行Test1()构造方法,打印出  3:t1 i=2 n=2,第1步语句执行完毕,接着执行第2步。

    (3)   分析同上,逐步打印出答案。

    为了好理解,下面附上一张图,挨着挨着看思路还是很清楚的哦!图画得有点儿乱:

     

    总结:大家只要掌握好执行的先后顺序,仔细分析题,就没有问题。

    2.继承情况下对象的初始化顺序

    属性、方法、构造方法和自由块都是类中的成员,在创建类的对象时,类中各成员的执行顺序:
    1.父类静态成员和静态初始化快,按在代码中出现的顺序依次执行。
    2.子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。
    3. 父类的实例成员和实例初始化块,按在代码中出现的顺序依次执行。
    4. 执行父类的构造方法。
    5.子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。
    6.执行子类的构造方法。

     1 package InitializationOrder;
     2 /**
     3  * 继承下的初始化顺序
     4  * @author TANJIAYI
     5  *
     6  */
     7 public class Test2 {
     8     public static void main(String[] args) {
     9         new Son();
    10     }
    11 }
    12 class Parent{  
    13       
    14     {  
    15         System.out.println("parent中的初始化块");  
    16     }  
    17     static{  
    18         System.out.println("parent中static初始化块");  
    19     }  
    20       
    21     public Parent(){  
    22         System.out.println("parent构造方法");  
    23     }  
    24 }  
    25   
    26 class Son extends Parent{  
    27     {  
    28         System.out.println("son中的初始化块");  
    29     }  
    30       
    31     static{  
    32         System.out.println("son中的static初始化块");  
    33     }  
    34       
    35     public Son(){  
    36         System.out.println("son构造方法");  
    37     }  
    38 }

    输出结果:

    1. 初始化块主要用于对象的初始化操作,在创建对象时调用,可以用于完成初始化属性值、加载其他的类的功能。
    2. 初始化块和构造方法功能类似,可以再创建对象的时候完成一些初始化的操作,一般的情况下,构造方法初始化和初始化块初始化可以通用。
    3. 构造方法在初始化的时候可以通过参数传递,但是初始化块不能,初始化块的初始化在构造方法之前执行,如果搞糟方法多次重载,此时可以考虑构造方法中共通的代码放到初始化块中进行初始化。

    补充:

    静态初始化块和非静态初始化块的区别?

    1. 非静态初始化块主要是用于对象的初始化操作,在每次创建对象的时都要调用一次,其执行顺序在构造方法之前。
    2. 在初始化块之前有static修饰,则为静态初始化块。由于非静态成员不能再静态方法中使用,同样也不能在静态初始化块中,因此,静态初始化块主要用于初始化静态变量和静态方法,静态初始化块只调用一次,是在类的第一次加载到内存时,并非一定要创建对象才执行。
    3. 静态初始化块比非静态初始化块先执行

    知了堂:www.zhiliaotang.com

    写得比较随意,很多地方,很不完全,希望广大的友友们,发现问题,给我留言,指正。

  • 相关阅读:
    实现翻页效果
    使用AHKActionSheet
    [翻译] GSProgressView
    [翻译] NSRegexTester
    下载时获取文件大小
    高级mask应用
    使用UILabel实现滚动字幕移动效果
    动画绘制水波纹
    能产生粒子效果的CAEmitterLayer
    使用UITableView实现图片视差效果
  • 原文地址:https://www.cnblogs.com/mcxiaotan/p/8059173.html
Copyright © 2011-2022 走看看