gpt4 book ai didi

java - 在声明时初始化的数组直到调用 super 构造函数之后才实际初始化

转载 作者:行者123 更新时间:2023-12-01 17:11:10 30 4
gpt4 key购买 nike

我遇到了一个看似奇怪的问题,尽管我知道这种设计背后可能有一些原因,并且想找出为什么会这样。

考虑两个类:Foo 和 Bar。 Bar 扩展了 Foo 并重写了 Foo 实现的方法。 Foo 非常简单:

public class Foo {
public Foo() {
System.out.println("Foo constructor");
someMethod();
}

public void someMethod() {
System.out.println("Foo.someMethod");
}
}

酒吧是问题所在。它定义了一个在构造函数外部初始化的数组(我不知道这个术语是什么)。我注意到,当从 Foo 调用 someMethod 时,数组尚未初始化,但在调用 super() 之后,数组已初始化。这是酒吧:

public class Bar extends Foo {
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

public Bar() {
super();
System.out.println("FooBar constructor");
if (a == null) System.out.println("FooBar a is null");
}

public void someMethod() {
if (a == null) System.out.println("FooBar.someMethod a is null");
}
}

这不太有意义。我想从 super 构造函数中调用的方法访问数组,但数组未初始化。我试图想出一个解决办法。我的第一个想法是在 Bar 的构造函数中初始化数组,但是在调用 super 之前仍然不会初始化它。

作为引用,输出如下:

Foo constructor
FooBar.someMethod a is null
FooBar constructor

为什么 Java 是这样设计的?最好的解决方法是什么?

最佳答案

父类(super class)构造函数必须在子类构造函数的其余部分开始之前成功完成。只有这样子类变量才会被初始化,所以在父类(super class)构造函数时,Bar中的a仍然是null。出现这种奇怪的情况是因为子类中重写了父类(super class)构造函数调用的方法,因此在子类本身初始化之前调用了子类方法。

有关为什么不好的更多信息Java leaking this in constructor 。这使得未完全初始化的对象可以被其他对象访问。

这里最好的做法是不要让父类(super class)构造函数调用在子类中被重写的方法。如果愿意的话,让 Bar 自己对 a 进行初始化/操作。

关于java - 在声明时初始化的数组直到调用 super 构造函数之后才实际初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23771186/

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