java中多级继承中构造函数调用的顺序[重复]

2024-03-06

//: c07:Sandwich.java
// Order of constructor calls.
// package c07;
// import com.bruceeckel.simpletest.*;

import java.util.*;

class Meal {
  Meal() { System.out.println("Meal()"); }
}

class Bread {
  Bread() { System.out.println("Bread()"); }
}

class Cheese {
  Cheese() { System.out.println("Cheese()"); }
}

class Lettuce {
  Lettuce() { System.out.println("Lettuce()"); }
}

class Lunch extends Meal {
  Lunch() { System.out.println("Lunch()"); }
}

class PortableLunch extends Lunch {
  PortableLunch() { System.out.println("PortableLunch()");}
}

public class Sandwich extends PortableLunch {
//  private static Test monitor = new Test();
  private Bread b = new Bread();
  private Cheese c = new Cheese();
  private Lettuce l = new Lettuce();
  public Sandwich() {
    System.out.println("Sandwich()");
  }
  public static void main(String[] args) {
    new Sandwich();
   /*
   monitor.expect(new String[] {
      "Meal()",
      "Lunch()",
      "PortableLunch()",
      "Bread()",
      "Cheese()",
      "Lettuce()",
      "Sandwich()"
    });
    // */
  }
} ///:~

这段代码的输出是

Meal()
Lunch()
PortableLunch()
Bread()
Cheese()
Lettuce()
Sandwich()  

既然类中的字段是按照声明的顺序创建的,为什么不呢?

Bread()
Cheese()
Lettuce()

出现在上面列表的顶部吗?

另外,这段代码试图做什么?

   monitor.expect(new String[] {
      "Meal()",
      "Lunch()",
      "PortableLunch()",
      "Bread()",
      "Cheese()",
      "Lettuce()",
      "Sandwich()"
    });  

起初我以为这是一个匿名类,但看起来不像。它初始化一个字符串数组吗?为什么它没有字符串变量的名称?请告诉我此处使用的编程结构的名称。


构造函数:

public Sandwich() {
    System.out.println("Sandwich()");
}

由编译器翻译为:

public Sandwich() {
    super();   // Compiler adds it if it is not explicitly added by programmer
    // All the instance variable initialization is moved here by the compiler.
    b = new Bread();
    c = new Cheese();
    l = new Lettuce();

    System.out.println("Sandwich()");
}

因此,构造函数中的第一个语句是超类构造函数的链接。事实上,任何构造函数中的第一个语句都链接到超类构造函数。这就是为什么首先是超类构造函数PortableLunch被调用,这再次链接对其超类构造函数的调用,因为super()由编译器添加(还记得吗?)。

构造函数调用的这种链接一直持续到继承层次结构顶部的类,从而调用Object类构造函数在最后。

现在,在每个超类构造函数执行完毕,并且所有超类字段都已初始化后,直接子类构造函数在super()称呼。最后又回到了Sandwitch()构造函数,现在初始化你的3字段。

所以,基本上你的字段最后被初始化,因此它们被打印在最后,就在之前Sandwitch()被打印。

参考JLS - §12.5 - 创建新类实例 http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5实例创建过程的详细说明。


至于你问题的第二部分:

monitor.expect(new String[] {
      "Meal()",
      "Lunch()",
      "PortableLunch()",
      "Bread()",
      "Cheese()",
      "Lettuce()",
      "Sandwich()"
    });  

这段代码正在创建一个未命名数组,并同时初始化一些字符串文字。它类似于创建命名数组的方式:

String[] arr = new String[] { "rohit", "jain" };
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中多级继承中构造函数调用的顺序[重复] 的相关文章

随机推荐