java - 如果 Java 中的类具有 IS-A 关系,它们是否以堆栈序列初始化?
问题描述
让我通过代码示例来解释我的问题,我有这个代码:
class A {
public A() {
System.out.println("In class A constructor");
}
static {
System.out.println("In class A static initializer");
}
}
class B extends A {
static {
System.out.println("In class B static initializer");
}
public B() {
System.out.println("In class B constructor");
}
}
public class C extends B {
public C() {
System.out.println("In class C constructor");
}
static {
System.out.println("In class C static initializer");
}
public static void main(String[] args) {
new C();
}
}
如果我们运行此代码,我们将打印出控制台:
在 A 类静态初始化器中
在 B 类静态初始化程序中
在 C 类静态初始化程序中
在 A 类构造函数中
在 B 类构造函数中
在 C 类构造函数中
如您所见,该类中的所有静态字段首先从 A 类调用到 B 类,然后是 C 类。然后我阅读了有关静态初始化程序的信息
类中声明的静态初始化器在类初始化时执行
我知道,如果我们只是查看构造函数。当我们调用时new C()
,我们将有一个调用堆栈:
“5”Object()
“4”个A()
电话super()
“3”个B()
电话super()
“2”个C()
电话super()
“1”main()
电话new C()
那么为什么 A、B、C 类中的所有静态初始化器都先完成,然后是构造函数呢?这是否意味着如果 Java 中的类具有 IS-A 关系,它们会在堆栈序列中初始化?
我认为我的问题可以通过这里详细初始化过程来回答,但我对所有细节都迷失了。希望有人能给我解释一下。
解决方案
构造函数在实例创建后运行。
C 的静态初始化程序必须在创建 C 的实例之前完成,因为:
类或接口类型 T 将在以下任何一项第一次出现之前立即初始化:
- T 是一个类,并创建了一个 T 的实例。
B 的静态初始化程序必须在 C 之前运行,A 在 B 之前运行,因为:
在一个类被初始化之前,它的直接超类必须被初始化,
推荐阅读
- amazon-web-services - 具有 TTL 并触发 Kinesis Firehose 的 DynamoDB 表
- c# - 如何评论为什么可以忽略捕获
- python - 使用networkx.read_gml python在.gml文件中重复边
- reactjs - 自定义 React Hooks 以及在 useEffect 挂钩中保留的内容
- visual-studio-code - 是否可以在赛普拉斯(VSCode)中从功能文件导航到步骤定义,反之亦然
- reactjs - 如何在 React JS 中获取多个复选框值?
- python - 将列表转换为 numpy 数组时,列表中的浮点值变为字符串
- shopify - Shopify - 编辑或替换图像资产
- php - PHP:如果搜索字符串排在第一位,则字符串替换不起作用
- java - Android - 从java向java脚本发送纬度和经度