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

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

转载于:https://www.cnblogs.com/lumingkui/archive/2012/12/08/2808200.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
静态代码块,构造块和构造方法是Java对象初始化的三种方式,它们各自具有不同的执行顺序和作用。它们的区别如下: 1. 静态代码块是在类被加载时执行的代码块,它只执行一次。静态代码块主要用于类的初始化,如静态变量的初始化等。 2. 构造块是在类定义的代码块,每次创建对象时都会执行,不论是调用无参构造函数还是有参构造函数。构造块用于初始化对象,如为对象的成员变量分配内存等。 3. 构造方法也是用于对象的初始化,但是它可以接收参数。构造方法用于为对象的成员变量赋初值。 下面是一个例子,可以帮助理解它们之间的关系: ```java public class BlockTest { static { System.out.println("静态代码块执行"); } { System.out.println("构造块执行"); } public BlockTest() { System.out.println("无参构造器执行"); } public BlockTest(int a) { System.out.println("有参构造器执行"); } public static void main(String[] args) { BlockTest bt1 = new BlockTest(); BlockTest bt2 = new BlockTest(10); } } ``` 运行以上代码,输出结果如下: ``` 静态代码块执行 构造块执行 无参构造器执行 构造块执行 有参构造器执行 ``` 可以看出,静态代码块是在类被加载时执行的,构造块是每次创建对象时都会执行的,而构造方法是用于为对象的成员变量赋初值的。 需要注意的是,虽然静态代码块和构造块都用于对象的初始化,但是它们的执行顺序是有区别的。静态代码块只会在类初始化时执行一次,而构造块则会在对象创建时执行。因此,静态代码块先于构造块执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值