子类、父类、静态成员变量,构造函数的执行顺序

Java程序在初始化工作可以在许多不同的代码块中来完成(例如静态代码块、构造函数等),

它们的执行顺序如下:

父类静态代变量、

父类静态代码块、

子类静态变量、

子类静态代码块、

父类非静态变量(父类实例成员变量)、

父类构造函数、

子类非静态变量(子类实例成员变量)、

子类构造函数。

例如下列程序:

package test;
 
class Father{
    public static Test staticFathermember=new Test("父类静态成员变量");
    public Test instanceFatherMember=new Test("父类实例成员变量");
//    static Father()            //不存在构造函数
//    {
//        Test staticFatherMethod=new Test("父类静态构造函数执行");//父类静态构造函数;
//    }
    public Father(){
        Test t=new Test("父类实例构造函数执行");
    }
}
class Son extends Father{
    public static Test staticSonMember=new Test("子类静态成员变量的执行");
    public Test instanceStaticSonMember=new Test("子类实例成员 执行");
    
//    static Son(){
//        Test staticMethod=new Test("子类静态构造函数执行");
//    }
    public Son(){
        Test instanceSonMethod=new Test("子类实例构造函数执行");
    }
}
public class Test{
    
    public Test(String str){
        System.out.println(str);
    }
    public static void main(String[] args){
        Son s=new Son();
    }
}
执行结果为:
父类静态成员变量
子类静态成员变量的执行
父类实例成员变量
父类实例构造函数执行
子类实例成员 执行
子类实例构造函数执行

下面的程序更清楚的表现了类变量的初始化过程。首先定义一个Price类,该Price类里面有一个静态的InitPrice变量,用于代表初始价格。每次创建Price实例时,系统都会以initPrice为基础,减去当前打折价格(由discount参数代表),即得到该Price的currentPrice变量值
代码如下:
class Price{
    //类成员是Price实例
    final static Price INSTANCE = new Price(2.8);
    //定义一个类变量
    static double initPrice=20;
    //定义该Price的currentPrice实例变量
    double currentPrice;
    public Price(double discount){
        //根据静态变量计算实例变量
        currentPrice=initPrice-discount;
    }
}
 
public class PriceTest{
    public static void main(String[] args){
        //通过price的INSTANCE访问currentPrice实例变量
        System.out.println(Price.INSTANCE.currentPrice);    //  1
        //显示创建price实例
        Price p=new Price(2.8);
        //通过显式创建的Price实例访问currentPrice实例变量
        System.out.println(p.currentPrice);                //   2
    }
}
上面的程序1,2行代码都访问了Price实例的currentprice实例变量,而且程序都是通过new Price(2.8);来创建实例的。从表面上看,程序输出两个Price的currentPrice都应该返回17.2,但实际上运行的结果并没有输出17.2.而是输出-2.8和17.2
如果每次仅仅停留在代码的表面上看这个问题,往往很难得到正确的结果,下面将从内存的角度来分析这个程序。第一次用到price类时,程序开始对Price类进行初始化,初始化分成以下两个阶段。
1)系统为Price的两个类变量分配内存空间。
2)按初始化代码的排列顺序对类变量执行初始化。
初始化第一阶段,系统先为INSTANCE、initPrice两个类变量分配内存空间,此时INSTANCE、initPrice的值默认值为null和0.0。接着初始化第二阶段,程序按顺序一次为INSTANCE、initPrice进行赋值。对INSTANCE赋值时要调用Price(2.8),创建Price实例,此时立即执行程序中的粗体字代码为currentPrice赋值,此时initPrice类变量为0,因此,赋值结果是currentPrice等于-2.8.接下来,程序再次将initPrice赋值为20,但此时对INSTANCE的currentPrice实例变量已经不起作用了。
————————————————
版权声明:本文为CSDN博主「完美风暴4」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值