有没有办法解决由两个相互引用的枚举引起的类加载问题?
我有两组枚举,Foo 和 Bar,定义如下:
public class EnumTest {
public enum Foo {
A(Bar.Alpha),
B(Bar.Delta),
C(Bar.Alpha);
private Foo(Bar b) {
this.b = b;
}
public final Bar b;
}
public enum Bar {
Alpha(Foo.A),
Beta(Foo.C),
Delta(Foo.C);
private Bar(Foo f) {
this.f = f;
}
public final Foo f;
}
public static void main (String[] args) {
for (Foo f: Foo.values()) {
System.out.println(f + " bar " + f.b);
}
for (Bar b: Bar.values()) {
System.out.println(b + " foo " + b.f);
}
}
}
上面的代码作为输出产生:
A bar Alpha
B bar Delta
C bar Alpha
Alpha foo null
Beta foo null
Delta foo null
我明白为什么会发生 - JVM 开始类加载 Foo;它在 Foo.A 的构造函数中看到了 Bar.Alpha,所以它开始类加载 Bar。它在对 Bar.Alpha 的构造函数的调用中看到了 Foo.A 引用,但是(因为我们仍在 Foo.A 的构造函数中)此时 Foo.A 为空,因此 Bar.Alpha 的构造函数传递了一个空值。如果我反转两个 for 循环(或以其他方式在 Foo 之前引用 Bar),输出会发生变化,因此 Bar 的值都是正确的,但 Foo 的值不是。
有没有办法解决这个问题?我知道我可以在第三堂课中创建一个静态地图和一个静态地图,但这对我来说感觉相当骇人。我还可以创建引用外部映射的 Foo.getBar() 和 Bar.getFoo() 方法,因此它甚至不会更改我的接口(我使用的实际类使用检查器而不是公共字段),但它仍然感觉对我来说有点不干净。
(我在实际系统中这样做的原因:Foo 和 Bar 表示 2 个应用程序相互发送的消息类型;Foo.b 和 Bar.f 字段表示给定消息的预期响应类型 - 所以在我的示例代码,当 app_1 收到 Foo.A 时,需要回复 Bar.Alpha,反之亦然。)
提前致谢!