大家先看下下面这段代码的结果应该是多少?
public class ParentObjectInit {
public void test() {
}
public ParentObjectInit() {
test();
}
public static void main(String[] args) {
new ChildObjectInit();
}
}
class ChildObjectInit extends ParentObjectInit {
private int instanceValue = 20;
public void test() {
System.out.println("instance1 value is: " + instanceValue);
}
}
结果调试出来是20还是0呢?
*******************************************************************
(1)类中属性缺省初始化和显示初始化:
*******************************************************************
public class ParentObjectInit {
public void test() {
}
public ParentObjectInit() {
test();
}
public static void main(String[] args) {
//先调用父类ParentObjectInit 的构造器
new ChildObjectInit();
}
}
class ChildObjectInit extends ParentObjectInit {
//属性显示初始化在调用本类构造器之后
private int instanceValue = 20;
//进入ChildObjectInit类的构造器后,instanceValue值为20
public ChildObjectInit() {
System.out.println("instance1 value is: " + instanceValue);
}
// 在调用ChildObjectInit类构造器前打印
public void test() {
System.out.println("instance1 value is: " + instanceValue);
}
}
过程如下:
上面程序可以说明的是:直到调用完父类ParentObjectInit 的构造方法之后,接着才对其成员变量instanceValue 显式的初始化操作,即将赋值20。
上面代码中的private int instanceValue = 20;定义应看成两部分:第一部分是定义变量,第二部分是给变量赋值。非static属性定义(缺省初始化)位于父类ParentObjectInit 构造方法之前,非static属性显示赋值位于父类ParentObjectInit 构造方法之后。
在父类ParentObjectInit 的构造方法执行时,根据多态性,它会去调用子类中定义的test()方法,可是,这时候,子类中的成员变量还没执行显式初始化操作, 对于private int instanceValue = 20;定义,instanceValue 的值为默认的初始化值0,所以,这时候在test方法中打印出的值为0。
备注:
private int instanceValue = 20;改为static修饰,其结果就是20,因为static属性在构造器调用之前就已经初始化了,并之后不会改变,属于整个类共享。
*******************************************************************
(2)类中对象初始化流程:
*******************************************************************
class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
}
class Cupboard {
//非静态初始化块
{
Bowl b1 = new Bowl(1);
}
//静态初始化块
static{
Bowl b2 = new Bowl(2);
}
/**
* 非静态实例属性
*/
Bowl b3 = new Bowl(3);
/**
* 静态实例属性
*/
static Bowl b4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
}
void f3(int marker) {
System.out.println("f3(" + marker + ")");
}
/**
* 静态实例属性
*/
static Bowl b5 = new Bowl(5);
}
class StaticDataInit {
public static void main(String[] args) {
Cupboard t3 = new Cupboard();
t3.f3(1);
}
/**
* 和在main()里面用Cupboard t3 = new Cupboard();结果等价
*/
// static Cupboard t3 = new Cupboard();
}
运行结果为:
Bowl(2) 先调用static初始化块
Bowl(4) 顺序初始化static属性b4和b5
Bowl(5) ...
Bowl(1) 调用非static初始化块
Bowl(3) 调用非static实例属性
Cupboard() 调用类Cupboard的构造器
f3(1) 对象t3调用f3方法
备注:如果将上面程序最后一句 static Cupboard t3 = new Cupboard();
注释解开。
运行结果为:
//static Cupboard t3 = new Cupboard();初始化的结果
Bowl(2)
Bowl(4)
Bowl(5)
Bowl(1)
Bowl(3)
Cupboard()
//创建对象t3并调用方法f3的结果
Bowl(1)
Bowl(3)
Cupboard()
f3(1)
//说明static属性和static块只在对象第一次初始化或static属性第一次初始化时赋值,以后不变
************************************************************************
形如:
public class A{
private int a = 100;
public A(){
//...
}
public static void main(String[] args){
new A();
}
}
//属性a的缺省值为0,在调用构造器A()之前,属性a的值是0。
//仅当调用到构造器A()后才将100显示地赋给属性a,之后再执行构造器中的逻辑。
总结:当一个类A中的对象a初始化时,依次先初始化其static初始化块,static属性,非static初始化块(...)和非static属性(缺省初始化)。然后再调用类A的构造器对A中的属性进行显示初始化。
posted on 2007-06-01 16:40
cheng 阅读(1237)
评论(0) 编辑 收藏 所属分类:
JBS