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对象时,会重复以上创建过程,就可以得到以上结果。

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

posted @ 2012-12-08 00:26  扳掘de  阅读(983)  评论(0编辑  收藏  举报