Java 枚举:两种枚举类型,每种都包含对彼此的引用?
有没有办法解决由两个相互引用的枚举引起的类加载问题?
我有两组枚举,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 的值不是。
有没有办法解决这个问题?我知道我可以在3rd类中创建静态地图和静态地图,但这对我来说感觉相当麻烦。我还可以制作引用外部映射的Foo.getBar()和Bar.getFoo()方法,这样它甚至不会改变我的界面(我的实际类使用检查器而不是公共字段),但它仍然感觉有点不干净。
(我在实际系统中这样做的原因:Foo和Bar表示2个应用程序相互发送的消息类型;Foo.b和Bar.f字段表示给定消息的预期响应类型 - 因此在我的示例代码中,当app_1收到Foo.A时,它需要使用Bar.Alpha进行回复,反之亦然。
提前致谢!