子类、父类、静态成员变量,构造函数的执行顺序
2015-04-17 11:24
281 查看
Java程序在初始化工作可以在许多不同的代码块中来完成(例如静态代码块、构造函数等),
它们的执行顺序如下:
父类静态代变量、
父类静态代码块、
子类静态变量、
子类静态代码块、
父类非静态变量(父类实例成员变量)、
父类构造函数、
子类非静态变量(子类实例成员变量)、
子类构造函数。
例如下列程序:
执行结果为:
下面的程序更清楚的表现了类变量的初始化过程。首先定义一个Price类,该Price类里面有一个静态的InitPrice变量,用于代表初始价格。每次创建Price实例时,系统都会以initPrice为基础,减去当前打折价格(由discount参数代表),即得到该Price的currentPrice变量值
代码如下:
如果每次仅仅停留在代码的表面上看这个问题,往往很难得到正确的结果,下面将从内存的角度来分析这个程序。第一次用到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实例变量已经不起作用了。
它们的执行顺序如下:
父类静态代变量、
父类静态代码块、
子类静态变量、
子类静态代码块、
父类非静态变量(父类实例成员变量)、
父类构造函数、
子类非静态变量(子类实例成员变量)、
子类构造函数。
例如下列程序:
执行结果为:
父类静态成员变量 子类静态成员变量的执行 父类实例成员变量 父类实例构造函数执行 子类实例成员 执行 子类实例构造函数执行
下面的程序更清楚的表现了类变量的初始化过程。首先定义一个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实例变量已经不起作用了。
相关文章推荐
- [C#]父类与子类的静态成员变量、实例成员变量、构造函数的执行顺序
- [C#]父类与子类的静态成员变量、实例成员变量、构造函数的执行顺序
- [C++]父类与子类的静态成员变量、实例成员变量、构造函数的执行顺序
- 【转】C#父类与子类的静态成员变量、实例成员变量、构造函数的执行顺序
- 父类,子类,静态属性,静态代码块,构造代码块,构造函数,执行顺序
- static,构造函数,子类,父类执行顺序
- Java 父类与子类初始化块,静态块,构造函数执行顺序
- java中父类与子类构造函数的执行顺序
- static,构造函数,子类,父类执行顺序
- 父类 子类 动态代码块 静态代码块 构造函数 执行顺序
- Java对象的构造过程---子类继承父类时(非)静态块及构造函数等的执行顺序
- 父类的成员对象、父类、子类的构造函数的执行顺序
- Java父类与子类中静态代码块 实例代码块 静态变量 实例变量 构造函数执行顺序
- 父类和子类静态代码块、非静态代码块、构造函数(方法)执行的先后顺序问题
- 继承中,父类与子类都有静态代码块和构造函数的时执行顺序
- 子类A继承父类B, A a = new A(); 则父类B构造函数、父类B静态代码块、父类B非静态代码块、子类A构造函数、子类A静态代码块、子类A非静态代码块 执行的先后顺序是?
- 有父类的子类实例化时,子类与父类的成员变量,构造函数,代码块的执行顺序
- java继承中父类和子类静态、非静态代码块,构造函数,静态方法的执行顺序
- static,构造函数,子类,父类执行顺序
- 父类 子类 动态代码块 静态代码块 构造函数 执行顺序