深入分析Java对象的建构顺序

发表于:2013-6-18 09:37

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

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

  对于下面的代码,许多有经验的程序员都没能给出正确的答案。如果你能只看代码给出的答案和文章末尾出给出大答案一致,那么你已经掌握了Java对象的建构顺序,中间的分析可以不用看了。

/**
  * 父类Foo,实现控制台输出
  *
  * @author youngto
  * @since 2013-01-25
  */
 class Foo {
 
     private int index = 100;
    
     //静态代码块
     static {       
         System.out.println("Foo static");
     }
    
     //初始化代码块
     {       
         System.out.println("Foo initialization");
     }
    
     public Foo() {
         System.out.println("Foo constructor");
         System.out.println(printIndex());
     }
    
     protected int printIndex() {
         return index;
     }
    
 }
 
 /**
  * 子类Bar,实现控制台输出
  *
  * @author youngto
  * @since 2013-01-25
  */
 public class Bar extends Foo{
    
     private int index = 100;
     static Bar bar = new Bar();
    
     //静态代码块
     static{
         System.out.println("Bar static");
     }
    
     //初始化代码块
     {
         System.out.println("Bar initialization");
     }
    
     public Bar() {
        System.out.println("Bar constructor");
        System.out.println(printIndex());
     }
    
     @Override
     protected int printIndex() {
         System.out.println(bar);
         return index;
     }
    
     public static void main(String[] args) {
         Foo foo = new Bar();
         System.out.println(foo.printIndex());
         foo = new Bar();
     }
 
 }

  在对象建构过程中。为确保其正确性,以下事件一定会以固定顺序发生:

  a、从heap之中分配内存,用以存放全部的 instance 变量以及这个对象连同其 superclasses的实现专属数据(implementation-specific data)。所谓「实现专属数据」包括指向“class and method data的指针。

  b、 对象的Instance变量被初始化为其相应的缺省值。

  c、调用most derived class(最深层派生类)的构造函数(constructor)(注:事实上,构造函数被.class文件中的一个initialization method(初始化函数)替换了。Initialization method是名为<init>的特殊函数,由Java编译器安放在.class文件里。其中包含[构造函数代码]、[instance变量之初始化代码],以及[调用superclass Initialization method]之代码。)。构造函致做的第一件事就是调用superclass的构造函数。这个程序一直反复持续到 java.lang.object构适函数被调用为止。一定要记住,java.lang.object是一切java对象的base class。

  d、所有对象的静态代码块或静态字段先获得执行,优先级从父类开始。

  e、在构造函数本体执行之前,所有 instance 变量的初值设定式(initializers)和初始化区(initialization blocks)先获得执行,然后才执行构造函数本体。于是base class的构造函数最先执行,most derived class的构造函数最后执行。这使得任何class的构造函数都能放心大胆地使用其任何superclass 的instance 变量。

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

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

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

沪ICP备05003035号

沪公网安备 31010102002173号