Java对象创建过程-成员初始化顺序 (转)

前几天开始重读《Java编程思想(第3版)》,对Java对象的创建过程、成员初始化顺序(尤其是涉及到组合和继承的情况下)作一下梳理总结。
书中第4章初始化与清理中对Java对象的创建过程总结如下:
假设有个名为Dog的类

当首次创建型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件。
然后载入Dog.class(这将创建一个Class对象),有关静态初始化的动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次。
当你用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。
这块存储空间会被清零,这就自动地将Dog中的所有基本类型数据设置成了默认值(对数字来说就是0,对布尔型和字符型也相同),而引用则被置成了null。
执行所有出现于域定义处的初始化动作。
执行构造器。
没有涉及到继承的时候,这个过程描述已经很清晰了,那么如果涉及到继承呢,看下面一段示例代码:
Java代码

Java代码 复制代码
  1. // Mouse4j.java      
  2. package com.mouse4j.simpletest;      
  3. // 静态字段类      
  4. class StaticField {      
  5.     private String s;      
  6.     StaticField(String s) {      
  7.         this.s = s;      
  8.         System.out.println("I am static field " + s);      
  9.     }       
  10. }      
  11. // 与静态字段相对的普通字段      
  12. class NormalField {      
  13.     private String s;      
  14.     NormalField(String s) {      
  15.         this.s= s;      
  16.         System.out.println("I am mormal field " + s);      
  17.     }      
  18. }      
  19. // 特点类      
  20. class Characteristic {      
  21.     private String s;      
  22.     Characteristic(String s) {      
  23.         this.s = s;      
  24.         System.out.println("Creating Characteristic " + s);      
  25.     }       
  26. }      
  27. // 描述类      
  28. class Description {      
  29.     // 注释1:在此例中如果用于组合的类中也包含static字段      
  30.     // public static StaticField dStr = new StaticField("Description");      
  31.           
  32.     // 注释2:在此例中如果用于组合的类中也包含在域定义处初始化      
  33.     // private NormalField dStr1 = new NormalField("Description");      
  34.     private String s;      
  35.     Description(String s) {      
  36.         this.s = s;      
  37.         System.out.println("Creating Description " + s);      
  38.     }       
  39. }      
  40. class Animal {      
  41.     public static StaticField AnimalStr = new StaticField("Animal");      
  42.     private Characteristic c = new Characteristic("Animal Characteristic");      
  43.     private Description d = new Description("Animal Description");      
  44.     Animal() {      
  45.         System.out.println("Animal()");      
  46.     }      
  47. }      
  48. class Mouse extends Animal{      
  49.     public static StaticField MouseStr = new StaticField("Mouse");      
  50.     private Characteristic c = new Characteristic("Mouse Characteristic");      
  51.     private Description d = new Description("Mouse Description");      
  52.     Mouse() {      
  53.         System.out.println("Mouse()");      
  54.     }      
  55. }      
  56. public class Mouse4j extends Mouse{      
  57.     public static StaticField Mouse4jStr = new StaticField("Mouse4j");      
  58.     private Characteristic c = new Characteristic("Mouse4j Characteristic");      
  59.     private Description d = new Description("Mouse4j Description");      
  60.     Mouse4j() {      
  61.         System.out.println("Mouse4j()");      
  62.     }      
  63.      
  64.     public static void main(String[] args) {      
  65.         new Mouse4j();      
  66.     }      
  67.      
  68. }    
// Mouse4j.java   
package com.mouse4j.simpletest;   
// 静态字段类   
class StaticField {   
    private String s;   
    StaticField(String s) {   
        this.s = s;   
        System.out.println("I am static field " + s);   
    }    
}   
// 与静态字段相对的普通字段   
class NormalField {   
    private String s;   
    NormalField(String s) {   
        this.s= s;   
        System.out.println("I am mormal field " + s);   
    }   
}   
// 特点类   
class Characteristic {   
    private String s;   
    Characteristic(String s) {   
        this.s = s;   
        System.out.println("Creating Characteristic " + s);   
    }    
}   
// 描述类   
class Description {   
    // 注释1:在此例中如果用于组合的类中也包含static字段   
    // public static StaticField dStr = new StaticField("Description");   
       
    // 注释2:在此例中如果用于组合的类中也包含在域定义处初始化   
    // private NormalField dStr1 = new NormalField("Description");   
    private String s;   
    Description(String s) {   
        this.s = s;   
        System.out.println("Creating Description " + s);   
    }    
}   
class Animal {   
    public static StaticField AnimalStr = new StaticField("Animal");   
    private Characteristic c = new Characteristic("Animal Characteristic");   
    private Description d = new Description("Animal Description");   
    Animal() {   
        System.out.println("Animal()");   
    }   
}   
class Mouse extends Animal{   
    public static StaticField MouseStr = new StaticField("Mouse");   
    private Characteristic c = new Characteristic("Mouse Characteristic");   
    private Description d = new Description("Mouse Description");   
    Mouse() {   
        System.out.println("Mouse()");   
    }   
}   
public class Mouse4j extends Mouse{   
    public static StaticField Mouse4jStr = new StaticField("Mouse4j");   
    private Characteristic c = new Characteristic("Mouse4j Characteristic");   
    private Description d = new Description("Mouse4j Description");   
    Mouse4j() {   
        System.out.println("Mouse4j()");   
    }   
  
    public static void main(String[] args) {   
        new Mouse4j();   
    }   
  
}  


程序执行输出如下:

Console 写道

Java代码 复制代码
  1. I am static field Animal    
  2. I am static field Mouse    
  3. I am static field Mouse4j    
  4. Creating Characteristic Animal Characteristic    
  5. Creating Description Animal Description    
  6. Animal()    
  7. Creating Characteristic Mouse Characteristic    
  8. Creating Description Mouse Description    
  9. Mouse()    
  10. Creating Characteristic Mouse4j Characteristic    
  11. Creating Description Mouse4j Description    
  12. Mouse4j()   
I am static field Animal 
I am static field Mouse 
I am static field Mouse4j 
Creating Characteristic Animal Characteristic 
Creating Description Animal Description 
Animal() 
Creating Characteristic Mouse Characteristic 
Creating Description Mouse Description 
Mouse() 
Creating Characteristic Mouse4j Characteristic 
Creating Description Mouse4j Description 
Mouse4j() 




从程序输出可以看出:

当首次创建型为Mouse4j的对象时,Java解释器查找类路径,定位Mouse4j.class文件。
Java解释器会根据Mouse4j.class定位其基类Mouse.class、再根据Mouse.class定位到基类Animal.class文件,有关静态初始化的动作从基类到子类依次执行。
当你用new Mouse4j()创建对象的时候,首先将在堆上为Mouse4j对象(包括其基类Mouse和Animal中的域)分配足够的存储空间。
这块存储空间会被清零,这就自动地将Mouse4j中的所有基本类型数据(包括其基类Mouse和Animal中的)设置成了默认值(对数字来说就是0,对布尔型和字符型也相同),而引用(包括其基类Mouse和Animal中的)则被置成了null。
执行基类Animal中所有出现于域定义处的初始化动作。
执行基类Animal构造器。
执行基类Mouse中所有出现于域定义处的初始化动作。
执行基类Mouse构造器。
执行子类Mouse4j中所有出现于域定义处的初始化动作。
执行子类Mouse4j构造器。
第5~10步过程总结如下:
在为所创建对象的存储空间清零后,找到继承链中最上层的基类,执行a、b两步:
a.执行其出现在域定义处的初始化动作
b.然后再执行其构造器
然后从基类到子类依次执行这两步操作。

到这里,涉及到继承Java对象创建过程和成员初始化顺序就理清楚了~(《编程思想》中关于这一点的描述让我有点晕~还是用程序实践一下思路会比较清晰)
再看组合的情况,将程序代码中的注释1和注释2去掉,考虑用于组合的类Description中也包含static字段和在域定义处初始化的情况,程序执行结果如下:

Console 写道

Java代码 复制代码
  1. I am static field Animal    
  2. I am static field Mouse    
  3. I am static field Mouse4j    
  4. Creating Characteristic Animal Characteristic    
  5. I am static field Description    
  6. I am mormal field Description    
  7. Creating Description Animal Description    
  8. Animal()    
  9. Creating Characteristic Mouse Characteristic    
  10. I am mormal field Description    
  11. Creating Description Mouse Description    
  12. Mouse()    
  13. Creating Characteristic Mouse4j Characteristic    
  14. I am mormal field Description    
  15. Creating Description Mouse4j Description    
  16. Mouse4j()   
I am static field Animal 
I am static field Mouse 
I am static field Mouse4j 
Creating Characteristic Animal Characteristic 
I am static field Description 
I am mormal field Description 
Creating Description Animal Description 
Animal() 
Creating Characteristic Mouse Characteristic 
I am mormal field Description 
Creating Description Mouse Description 
Mouse() 
Creating Characteristic Mouse4j Characteristic 
I am mormal field Description 
Creating Description Mouse4j Description 
Mouse4j() 




可见Description对象的创建过程与成员初始化顺序与本文开头的Dog对象的例子一致。(The End)

对原文作者表示感谢!

http://329937021.iteye.com/blog/546885

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值