gpt4 book ai didi

java - 当嵌套枚举在其构造函数中引用父静态成员时,为什么会出现 NPE?

转载 作者:搜寻专家 更新时间:2023-11-01 02:00:01 24 4
gpt4 key购买 nike

重新创建的条件(据我所知):

  1. 嵌套枚举引用父静态成员
  2. 嵌套类
  3. 父类的静态成员将枚举作为嵌套类的构造函数参数
  4. enum 在父类中的任何其他内容之前被外部类引用

在线运行这段代码: https://repl.it/repls/PlushWorthlessNetworking

import java.util.ArrayList;

class Recreate {

private static ArrayList FEATURES = new ArrayList();

public enum Car {
TESLA(FEATURES);
Car(ArrayList l) { }
}

public static class Garage {
final Car car;

Garage(Car car) {
this.car = car;
}
}

public static Garage ONE_CAR_GARAGE = new Garage(Car.TESLA);
}

class Main {
public static void main(String[] args) {
// inclusion of this line causes the next line to NPE
System.out.println(Recreate.Car.TESLA);

System.out.println(Recreate.ONE_CAR_GARAGE.car.toString());
}
}

最佳答案

这是正在发生的事情:

  1. main方法开始执行
  2. 你引用Recreate.Car.TESLA
  3. 类加载器开始加载和初始化enum Car。如下所述,Recreate 类尚未加载或初始化。
  4. TESLA 的初始化程序是指 FEATURES
  5. 这会导致加载和初始化类 Recreate
  6. 作为 Recreate 静态初始化的一部分,加载、初始化类 Garage,并创建实例 ONE_CAR_GARAGE

这里的问题是,此时enum Car的构造还没有完成,Car.TESLA的值为null .

尽管类可能是嵌套的,但嵌套类的加载和初始化并不是外部类初始化的一部分。它们可能看起来嵌套在源代码中,但每个类都是独立的。静态嵌套类相当于顶级类。非静态类也一样,但能够通过隐藏引用引用包含类中的成员。

如果您在调试器中运行它,在多个位置放置断点,并检查每个断点处的堆栈,您就可以亲眼看到。

我在 Eclipse 中使用以下代码对此进行了测试/调试,并在指示的位置设置了断点。它与您的代码略有不同,但行为不应不同:

public class Foo5
{
static class Recreate {

private static ArrayList FEATURES = new ArrayList();

public enum Car {
TESLA(FEATURES);
Car(ArrayList l) {
System.out.println("car"); // *** Breakpoint ***
}
}
public static Garage ONE_CAR_GARAGE = new Garage(Car.TESLA);

public static class Garage {
final Car car;

Garage(Car car) {
this.car = car; // *** Breakpoint ***
}
}
}

public static void main(String[] args) throws Exception {
Recreate.Car car = Recreate.Car.TESLA;
System.out.println(Recreate.Car.TESLA);
System.out.println(Recreate.ONE_CAR_GARAGE.car.toString());
}
}

您遇到的第一个断点将是 Garage(Car car) 构造函数中的断点。此时检查堆栈,您会看到

Foo5$Recreate$Garage.<init>(Foo5$Recreate$Car) line: 23 
Foo5$Recreate.<clinit>() line: 17
Foo5$Recreate$Car.<clinit>() line: 12
Foo5.main(String[]) line: 29

所以当 Garage 构造函数被调用时,它还没有从创建 Car 返回。这是由您在类之间创建的错综复杂的依赖关系决定的,因此解决方案是解开依赖关系。如何做到这一点取决于您的最终目标。

关于java - 当嵌套枚举在其构造函数中引用父静态成员时,为什么会出现 NPE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51317485/

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