[转]Java中代码块和构造器的调用机制

在平常学习中我们经常会碰到代码块和构造器的问题,下面我用一个简单的例子来解释它的运行机制。

我们先建立三个类,它们的关系是

Animal  (Brid的父类)

     |

  Brid  (Eagle的父类)

     |

  Eagle

代码如下:

public class Animal { 
    
    static{ 
        System.out.println("Animal的static代码块"); 
    } 
    
    { 
        System.out.println("Animal的普通代码块"); 
    } 
    
    public Animal(){ 
        System.out.println("Animal的无参构造器"); 
    } 
    
}

public class Brid extends Animal{ 
    
    static { 
        System.out.println("Brid的static代码块"); 
    } 
    
    { 
        System.out.println("Brid的普通代码块"); 
    } 
    
    public Brid(){ 
        System.out.println("Brid的无参构造器"); 
    } 
    
    public Brid(String str){ 
        this(); 
        System.out.println(str); 
    } 
}

public class Eagle extends Brid{ 
    
    static { 
        System.out.println("Eagle的static代码块"); 
    } 
    
    { 
        System.out.println("Eagle的普通代码块"); 
    } 
    
    public Eagle(){ 
        super("Eagle实例调用Brid含参数构造器"); 
        System.out.println("Eagle的无参构造器"); 
    } 
    
    public Eagle(String str){ 
        System.out.println("Eagle的含参数构造器"); 
    } 
    
    public static void main(String[] args){ 
        new Eagle(); 
        new Eagle(); 
    } 
}

运行以后得到的结果为:

Animal的static代码块       ---1 
Brid的static代码块           ---2 
Eagle的static代码块        ---3    前三行是在载入类的时候产生的 
Animal的普通代码块        ---4 
Animal的无参构造器        ---5 
Brid的普通代码块            ---6 
Brid的无参构造器            ---7 
Eagle实例调用Brid含参数构造器   ---8 
Eagle的普通代码块         ---9 
Eagle的无参构造器         ---10   4到10行是创建第一个类对象时产生 
Animal的普通代码块        ---11 
Animal的无参构造器        ---12 
Brid的普通代码块            ---13 
Brid的无参构造器            ---14 
Eagle实例调用Brid含参数构造器  ---15 
Eagle的普通代码块         ---16 
Eagle的无参构造器         ---17   在创建第二个类对象时由于已经载入了三个类,就可以直接创建了 

 

我们来分析一下结果,当程序运行main主函数时,首先需要载入当前类,而在载入当前类之前需要载入父类,由于static代码块是类代码块,在载入类的同时会载入static代码块,这就产生了前三行。然后会创建当前类对象,首先会创建父类对象,普通代码块和构造器会在创建类对象时同时执行,创建第一个对象时产生了4到10行。创建第二个对象时由于已经载入了三个类,所以就不会出现前三行,直接产生了11到17行。

我们简述一下整个创建对象的过程:

首先要明白,要想创建子类对象就必须先建立其所有父类的对象

(1)new Eagle() 创建对象时,先检查Eagle类的构造器是否显示调用当前类或者父类构造器——Eagle无参构造器中显示调用了其父类的含参构造器,检查完后就上溯到父类Brid(由于显示调用了,就会覆盖子类隐式调用)(2)先检查Brid类的构造器是否显示调用当前类或者父类构造器——其含参构造器调用其无参构造器,检查完后就上溯到父类Animal(3)先检查Animal类的构造器是否显示调用当前类或者父类构造器——没有显示调用,继续上溯其父类,(此后不在控制台输出)依次类推直至上溯到Object类

(4)建立Animal对象,先执行普通代码块 

Animal的普通代码块  ---4 
Animal的无参构造器 ---5

(5)建立Brid对象,由于其子类显示调用了其含参构造器,就不再调用无参构造器去创建对象了

Brid的普通代码块 ---6 
Brid的无参构造器 ---7 
Eagle实例调用Brid含参数构造器 ---8 

(6)建立Eagle对象,由于已经显示调用了父类的含参构造器,即父类对象已创建,可得

Eagle的普通代码块 ---9 
Eagle的无参构造器 ---10

创建第二个Eagle对象时,会重复以上创建过程,就可以得到以上结果。

相信大家都已经了解了构造器的运行机制了。

 

出处:http://www.cnblogs.com/lumingkui/archive/2012/12/08/2808200.html

posted @ 2013-12-03 20:37  macemers  阅读(164)  评论(0编辑  收藏  举报