gpt4 book ai didi

java - java中多级继承中构造函数调用的顺序

转载 作者:IT老高 更新时间:2023-10-28 20:52:10 27 4
gpt4 key购买 nike

//: 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()");
}

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

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

现在,在每个父类(super class)构造函数执行完毕,并且所有父类(super class)字段都已初始化之后,直接子类构造函数在 super() 调用之后开始执行。最后回到 Sandwitch() 构造函数,它现在初始化你的 3 字段。

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

引用 JLS - §12.5 - Creation of New Class Instance 详细解释实例创建过程。


关于你的第二部分问题:

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

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

String[] arr = new String[] { "rohit", "jain" };

关于java - java中多级继承中构造函数调用的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17806342/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com