继承与初始化

       当存在继承的情况时,各变量的初始化情况变得更为复杂了(不关局部变量的事),我们有必要梳理一下。

先上一段代码:

class Insect{
    private int i = 9;
    protected int j;
    Insect(){
        System.out.println("i = " + i + ",j = " + j);
    }
    private static int x1 = printInit("static Insect.x1 initialized");
    public  int x2 = printInit("Shape.x2 initialized");
    static int printInit(String s) {
        System.out.println(s);
        return 47;
    }
}
public class Beetle extends Insect{
    private int k = printInit("Beetle.k initialized");
    public Beetle(){
        System.out.println("k = "+k);
        System.out.println("j = "+j);
    }
    public  int x1 = printInit("Circle.x2 initialized");
    private static int x2 = printInit("static Beetle.x2 initialized");
    public static void main(String[] args) {
        System.out.println("Beetle constructor");
        Beetle b = new Beetle();
    }
}

输出结果:

static Insect.x1 initialized
static Beetle.x2 initialized
Beetle constructor
Shape.x2 initialized
i = 9,j = 0
Beetle.k initialized
Circle.x2 initialized
k = 47
j = 0

由输出结果可以看出:先初始化基类的静态域==》子类的静态域==》基类的非静态成员变量==》基类的构造方法==》子类的非静态成员变量==》子类的构造方法。

总结:

      访问Beetle类时加载它的字节码时,发现它有一个基类,于是开始加载它的基类(即使你不打算生成基类的对象),如果基类还有基类,则以此类推。字节码加载完毕后,根基类的静态域会先初始化,然后导出类,因为导出类很可能依赖基类的成员。

       至此,类加载完毕,对象就可以开始创建了。首先,对象的基本类型会被设置为0(等价0),引用对象被设置为null,之后基类的构造器被调用,导出类的构造器和基类的顺序一样。基类构造器调用后,实例变量按次序被初始化。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值