Think in Java之构造器的真正调用顺序

发表于:2012-3-01 09:30

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:yaerfeng    来源:51Testing软件测试网采编

分享:

  可见,调用类本身是最后完成初始化的,最先完成初始化的是最顶级的基类,所谓没有父亲,哪来的儿子。处于它们中间的是调用类本身拥有的子对象。因为你不可能在子对象初始化之前用本类调用它,所以它一定在本类调用之前,父类调用之后完成初始化的。

  那么这个说法是不是一定成立呢。结果是否定的。你必须知道JVM的编绎原理才可能知道,它究竟是如何工作的。

  我们来看下面这个例子,来解释为什么它不一定。因为在继承和重写的时候,这种情况变得有点诡异。

  深入探究:

  1. package com.tudou.t1;  
  2.  
  3. public class ConstrcutorTest2 {  
  4.     public static void main(String[] args) {  
  5.         new RoundGlyph(5);  
  6.     }  
  7. }  
  8.  
  9. class Glyph {  
  10.  
  11.     void draw() {  
  12.         System.out.println("Glyph draw()");  
  13.     }  
  14.  
  15.     Glyph() {  
  16.         System.out.println("Glyph before draw();");  
  17.         draw();  
  18.         System.out.println("Glyph after draw();");  
  19.     }  
  20. }  
  21.  
  22. class RoundGlyph extends Glyph {  
  23.     private int radius = 1;  
  24.  
  25.     RoundGlyph(int r) {  
  26.         radius = r;  
  27.         System.out.println("RoundGlyph(),radius:" + radius);  
  28.     }  
  29.  
  30.     void draw() {  
  31.         System.out.println("RoundGlyph.draw(),radius:" + radius);//此处打印是0,而不是1  
  32.     }  
  33. }

  控制台打印结果:

Glyph before draw();
RoundGlyph.draw(),radius:0
Glyph after draw();
RoundGlyph(),radius:5

  为什么RoundGlyph.draw(),radius:0这里会是0呢。

  默认的1哪去了?值自己会变么。其实上面的讲述并不完整。,而这正是解决谜题的关键所在。初始化的实际过程之前,实际在还有一步。

  0:在其他任何事物发生之前,将分配对象的存舍得空间初始化为二进制的零。

  而它后面的初始化顺序就是上面的3步。

  调用基类[即父类]构造器。这个步骤会不断反复递归下去,首先是构造器这种层次结构的根,然后是下一层导出类[即子类],等等。直到最底层的导出类。

  按声明顺序调用成员的初始化方法。

  调用导出类构造器的主体

  也就是说,实际上有4步,知道这些你对对象初始化构造器才可能有个清楚的认识。

  JAVA有更多的精髓等着人们去挖掘,而不仅仅是知道如何去使用它。

  因为你不知道什么时候它会出现意想不到的后果,而这个错误,可能你根本就想不出来。

  编写构造器时有一条准则:

  用尽可能简单的方法使对象进入正常状态,如果可以的话,避免调用其它方法。

  在构造器内唯一能够安全调用的那些方法是基类中的final或者private方法,这些方法不能被覆盖,因此也就不会出现令人惊讶的问题。

  你可能无法总是遵循这条准则,但是应该朝着它努力。

  学任何语言,请打好基础,它是你以后扩展的人生基石。

22/2<12
重磅发布,2022软件测试行业现状调查报告~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2023
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号