如何创建对象实例

上传人:woxinch****an2018 文档编号:38970808 上传时间:2018-05-10 格式:DOCX 页数:17 大小:74.88KB
返回 下载 相关 举报
如何创建对象实例_第1页
第1页 / 共17页
如何创建对象实例_第2页
第2页 / 共17页
如何创建对象实例_第3页
第3页 / 共17页
如何创建对象实例_第4页
第4页 / 共17页
如何创建对象实例_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《如何创建对象实例》由会员分享,可在线阅读,更多相关《如何创建对象实例(17页珍藏版)》请在金锄头文库上搜索。

1、 如何创建对象实例如何创建对象实例对象实例何时被创建,这个问题也许你用一句话就能回答完了。但是它的潜在陷阱却常常被人忽视,这个问题也许并不像你想的那么简单,不信请你耐心看下去。我前几天问一个同学,是不是在调用构造函数后,对象才被实例化?他不假思索的回答说是。请看下面代码:Java代码1. Date date=new Date();2.3. em.out.println(date.getTime();新手在刚接触构造函数这个概念的时候。他们常常得出这样的结论:对象实例是在调用构造函数后创建的。因为调用构造函数后,调用引用(date)的实例方法便不会报NullPointerException的错误

2、了。二、经验者的观点然而,稍稍有经验的Java程序员便会发现上面的解释并不正确。这点从构造函数中我们可以调用this关键字可以看出。请看下面代码:Java代码1. public class Test2.3. 4.5. public Test()6.7. 8.9. this.DoSomething();11. 12.13.14.15. private void DoSomething()16.17. 18.19. System.out.println(“do init“);20.21. 23. 这段代码中我们在构造函数中已经可以操作对象实例。这也就证明了构造函数其实只是用于初始化,早在进入构造函

3、数之前。对象实例便已经被创建了。三、父类构造函数当创建一个有父类的子类的时候。对象的实例又是何时被创建的呢?我们也许接触过下面经典的代码:Java代码1. public class BaseClass2. 3. public BaseClass()4. 5. System.out.println(“create base“);6. 7. 8. public class SubClass9. 10. public SubClass()11. 12. System.out.println(“create sub“);13. 14. public static void main(String ar

4、gs)15. 16. new SubClass();17. 18. 结 果是先输出create base,后输出create sub。这个结果看起来和现实世界完全一致,先有老爸,再有儿子。因此我相信有很多程序员跟我一样会认为new SubClass()的过程是:实例化BaseClass-调用BaseClass构造函数初始化-实例化SubClass-调 用SubClass构造函数初始化。然而非常不幸的是,这是个错误的观点。四、奇怪的代码以下代码是为了驳斥上面提到的错误观点。但是这种代码其实在工作中甚少出现。Java代码1. public class BaseClass2. 3. public B

5、aseClass()4.5. 6.7. System.out.println(“create base“);8.9. init();10.11. 12. protected void init() 13.14. System.out.println(“do init“);15. 16. 17.18. /20. public class SubClass21. 22. public SubClass()23. 24.25. System.out.println(“create sub“);26.27. 28. Override29.30. protected void init()32. 33.

6、34. assert this!=null;35.36. System.out.println(“now the working class is:“+this.getClass().getSimpleName();37.38. System.out.println(“in SubClass“);39.40. 41.42. public static void main(String args)44. 45.46. new SubClass();47.48. 49.50. 这段代码运行的结果是先调用父类的构造函数,再调用子类的init()方法,再调用子类的构造函数。这是一段奇妙的代码,子类的构

7、造函数居然不是子类第一个被执行的方法。我们早已习惯于通过super方便的调用父类的方法,但是好像从没这样尝试从父类调用子类的方法。再 次声明,这只是个示例。是为了与您一起探讨对象实例化的秘密。通过这个 示例,我们再次印证了开头的观点:早在构造函数被调用之前,实例便已被创造。若该对象有父类,则早在父类的构造函数被调用之前,实例也已被创造。这让 java显得有些不面向对象,原来老子儿子其实是一块儿出生的。五、奇怪但危险的代码本篇是对上篇奇怪代码的延续。但是这段代码更加具有疑惑性,理解不当将会让你出现致命失误。请看下面代码:Java代码1. public class BaseClass 2.3. p

8、ublic BaseClass()4.5. 6.7. System.out.println(“create base“);8.9. init();10.11. 12.13. protected void init() 14.15. System.out.println(“in base init“);16.17. 18.19. 20.21. public class SubClass extends BaseC22.23. int i=1024;24.25. String s=“13 leaf“;26.27.28.29. public SubClass()30.31. 32.33. Syste

9、m.out.println(“create sub“);34.35. init();36.37. 38.39. Override40.41. protected void init() 42.43. assert this!=null;44.45. System.out.println(“now the working class is:“+this.getClass().getSimpleName();46.47. System.out.println(“in SubClass“);48.49. /great line/50.51. System.out.println(i);52.53.

10、System.out.println(s);54.55. 56.57. public static void main(String args) 58.59. new SubClass();60.61. /oh!my god!62.63. 64.65. 这段代码相比上一篇,只是在子类中添加了一些成员变量。而我们的目标正是集中在讨论成员变量初始化的问题上。这段代码的执行顺序是:父类、子类实例化-调用父类构造函数-调用子类init()方法-调用子类构造函数-调用子类init()方法。最终的输出结果向我们揭示了成员变量初始化的秘密。当 父类构造函数调用子类的init()方法的时候。子类的成员变量统统

11、是 空的,这个空是指的低级初始化。(值类型为0,布尔类型为false,引用类型为null)。而当子类构造函数调用init()方法的时候,成员变量才真 正被初始化。这是一个危险的讯息,那就是使用父类构造函数调用子类时存在成员变量未初始化的风险。我们的讨论也到此为止了。再次回顾,总结一下实例何时被创建这个问题。我得出了以下结论:本文到此便结束了。鉴于本人才疏学浅,若是专业术语有错误,或是哪里讲的不对,也欢迎各位高手拍砖。附上第五篇中SubClass的部分字节码,方便大家深入理解:Java代码1. public SubClass();2.3. aload_0 this /aload_0是啥?4.5.

12、 invokespecial ques.BaseClass() 26 /调用父类构造函数7. aload_0 this8.9. sipush 1024 /初始化i成员变量10.11. putfield ques.SubClass.i : int 2812.13. aload_0 this14.15. ldc “13 leaf“ 30 /初始化s成员变量16.17. putfield ques.SubClass.s : java.lang.String 19. getstatic java.lang.System.out : java.io.PrintStream 3420.21. ldc “create sub“ 4022.23. invokevirtual java.io.PrintStream.println(java.lang.String) : void 4224.25. aload_0 this26.27. invokevirtual ques.SubClass.init() : void 48 /调用init28.29. return(psps:本文章来源于北大青鸟广安门校区官网):本文章来源于北大青鸟广安门校区官网)

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 高中教育

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号