`
miman2008
  • 浏览: 38110 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

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

分享到:
评论

相关推荐

    iOS版微信抢红包Tweak.zip小程序

    iOS版微信抢红包Tweak.zip小程序

    毕业设计&课设_篮球爱好者网站,含前后台管理功能及多种篮球相关内容展示.zip

    该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过严格测试运行成功才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

    基于springboot社区停车信息管理系统.zip

    基于springboot社区停车信息管理系统.zip

    基于springboot南皮站化验室管理系统源码数据库文档.zip

    基于springboot南皮站化验室管理系统源码数据库文档.zip

    重磅,更新!!!上市公司全要素生产率TFP数据及测算方法(OL、FE、LP、OP、GMM)(2000-2023年)

    ## 数据指标说明 全要素生产率(TFP)也可以称之为系统生产率。指生产单位(主要为企业)作为系统中的各个要素的综合生产率,以区别于要素生产率(如技术生产率)。测算公式为:全要素生产率=产出总量/全部资源投入量。 数据测算:包含OL、FE、LP、OP、GMM共五种TFP测算方法!数据结果包括excel和dta格式,其中重要指标包括证券代码,固定资产净额,营业总收入,营业收入,营业成本,销售费用,管理费用,财务费用,购建固定资产无形资产和其他长期资产支付的现金,支付给职工以及为职工支付的现金,员工人数,折旧摊销,行业代码,上市日期,AB股交叉码,退市日期,年末是否ST或PT等变量指标分析。文件包括计算方法说明及原始数据和代码。 数据名称:上市公司全要素生产率TFP数据及测算方法(OL、FE、LP、OP、GMM) 数据年份:2000-2023年 数据指标:证券代码、year、TFP_OLS、TFP_FE、TFP_LP1、TFP_OP、TFP_OPacf、TFP_GMM

    多种编程语言下算法实现资源汇总

    内容概要:本文详细总结了多种编程语言下常用的算法实现资源,涵盖Python、C++、Java等流行编程语言及其相关的开源平台、在线课程和权威书籍。对于每种语言而言,均提供了具体资源列表,包括开源项目、标准库支持、在线课程及专业书籍推荐。 适合人群:适用于所有希望深入研究并提高特定编程语言算法能力的学习者,无论是编程新手还是有一定经验的技术人员。 使用场景及目标:帮助开发者快速定位到合适的算法学习资料,无论是出于个人兴趣自学、面试准备或是实际工作中遇到的具体算法问题,都能找到合适的解决方案。 其他说明:文中提及多个在线学习平台和社区网站,不仅限于某一特定语言,对于跨学科或多元化技能培养也具有很高的参考价值。

    基于springboot的交通旅游订票系统源码数据库文档.zip

    基于springboot的交通旅游订票系统源码数据库文档.zip

    GO语言教程:基础知识与并发编程

    内容概要:本文档是一份详细的GO语言教程,涵盖了Go语言的基础语法、数据类型、控制结构、函数、结构体、接口以及并发编程等多个方面。主要内容包括Go语言的基本概念和历史背景、环境配置、基本语法(如变量、数据类型、控制结构)、函数定义与调用、高级特性(如闭包、可变参数)、自定义数据类型(如结构体、接口)以及并发编程(如goroutine、channel、select)等内容。每部分内容都附有具体的代码示例,帮助读者理解和掌握相关知识点。 适合人群:具备一定编程基础的开发者,尤其是希望深入学习和应用Go语言的技术人员。 使用场景及目标:①初学者通过本教程快速入门Go语言;②有一定经验的开发者系统复习和完善Go语言知识;③实际项目开发中利用Go语言解决高性能、高并发的编程问题。 阅读建议:本文档全面介绍了Go语言的各项基础知识和技术细节,建议按章节顺序逐步学习,通过动手实践代码示例加深理解。对于复杂的概念和技术点,可以通过查阅更多资料或进行深入研究来巩固知识。

    time_series_at_a_point.ipynb

    GEE训练教程

    memcached笔记资料

    memcached笔记资料,配套视频:https://www.bilibili.com/list/474327672?sid=4486766&spm_id_from=333.999.0.0&desc=1

    基于springboot校内跑腿业务系统源码数据库文档.zip

    基于springboot校内跑腿业务系统源码数据库文档.zip

    计算机控制光感自动窗帘控制系统设计.doc

    计算机控制光感自动窗帘控制系统设计.doc

    基于SpringBoot的校园服务系统源码数据库文档.zip

    基于SpringBoot的校园服务系统源码数据库文档.zip

    基于SpringBoot+Vue的美容店信息管理系统源码数据库文档.zip

    基于SpringBoot+Vue的美容店信息管理系统源码数据库文档.zip

    基于springboot程序设计基础课程辅助教学系统源码数据库文档.zip

    基于springboot程序设计基础课程辅助教学系统源码数据库文档.zip

    原生JS实现斗地主小游戏源码.zip

    这是一个原生的JS网页版斗地主小游戏,代码注释全。带有斗地主游戏基本的地主、选牌、提示、出牌、倒计时等功能。简单好玩,欢迎下载

    基于springboot亚运会志愿者管理系统源码数据库文档.zip

    基于springboot亚运会志愿者管理系统源码数据库文档.zip

    毕业设计&课设_含多功能的远程控制工具集(已停维护),含命令行、文件管理、桌面功能.zip

    该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过严格测试运行成功才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

    Sen2_NDVI_Max.txt

    GEE训练教程——Landsat5、8和Sentinel-2、DEM和各2哦想指数下载

    基于springboot家校合作平台源码数据库文档.zip

    基于springboot家校合作平台源码数据库文档.zip

Global site tag (gtag.js) - Google Analytics