gpt4 book ai didi

java - 为什么子类中的静态 block 没有被执行?

转载 作者:搜寻专家 更新时间:2023-11-01 03:51:56 26 4
gpt4 key购买 nike

这是代码

public class ClassResolution {
static class Parent {
public static String name;
static {
System.out.println("this is Parent");
name = "Parent";
}

}

static class Child extends Parent {
static {
System.out.println("this is Child");
name = "Child";
}

}

public static void main(String[] args) throws ClassNotFoundException {
System.out.println(Child.name);
}}

我期望的输出是:

this is Parent
this is Child
Child

但实际上是:

this is Parent
Parent

子类中的静态 block 似乎没有被执行,但为什么呢?这是反直觉的,不是吗?

补充:
为了更清楚,我在下面列出了 2 1 点:

  1. 正如@axtavt 所说,根据JLS 12.4.1 , 类 Child 已加载,但未初始化。
  2. 但是@Alexei Kaigorodov 指出,根据jvms-5.5 ,类 Child 应该被初始化,因为执行Child 类上的指令 getstatic。

你怎么看?

补充2:
@Alexei Kaigorodov 已经更新了他的想法,所以似乎没有分歧了。但我认为 Alexei Kaigorodov 的观点很有启发性,所以我把它留在那里。

谢谢大家

最佳答案

来自 JLS 12.4.1 :

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.
  • T is a class and a static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the field is not a constant variable (§4.12.4).
  • T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.

如您所见,这些都不会发生在您的代码中(请注意 name 是在 Parent 中声明的,而不是在 Child 中声明的),因此 Child 不会被初始化,它的静态 block 也不会被执行。

如果您执行某些操作来触发 Child 的初始化,您将获得预期的输出:

new Child();
System.out.println(Child.name);

但是请注意,静态字段不会被继承,因此 Child.nameParent.name 实际上指的是同一个字段。这就是为什么在实践中使用类似于您的示例的代码没有多大意义。

另请注意,尽管 Child.name 实际上是指 Parent.name,但它在字节码,因此您的代码会触发加载 Child,但不会触发其初始化。

关于java - 为什么子类中的静态 block 没有被执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24170682/

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