有没有办法解决由于两个枚举相互引用而导致的类加载问题?
我有两组枚举,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 此时为 null,因此 Bar.Alpha 的构造函数传递了 null。如果我反转两个 for 循环(或者以其他方式在 Foo 之前引用 Bar),则输出会发生更改,以便 Bar 的值全部正确,但 Foo 的值则不然。
有什么办法可以解决这个问题吗?我知道我可以在第三个类中创建一个静态映射和一个静态映射,但这对我来说感觉相当黑客。我还可以创建引用外部映射的 Foo.getBar() 和 Bar.getFoo() 方法,因此它甚至不会更改我的界面(我使用检查器而不是公共字段的实际类),但它仍然感觉对我来说有点不干净。
(我在实际系统中这样做的原因:Foo 和 Bar 代表 2 个应用程序相互发送的消息类型;Foo.b 和 Bar.f 字段代表给定消息的预期响应类型 - 所以在我的示例代码,当app_1收到Foo.A时,它需要回复Bar.Alpha,反之亦然。)
提前致谢!
最好的方法之一是使用枚举多态技术:
public class EnumTest {
public enum Foo {
A {
@Override
public Bar getBar() {
return Bar.Alpha;
}
},
B {
@Override
public Bar getBar() {
return Bar.Delta;
}
},
C {
@Override
public Bar getBar() {
return Bar.Alpha;
}
},
;
public abstract Bar getBar();
}
public enum Bar {
Alpha {
@Override
public Foo getFoo() {
return Foo.A;
}
},
Beta {
@Override
public Foo getFoo() {
return Foo.C;
}
},
Delta {
@Override
public Foo getFoo() {
return Foo.C;
}
},
;
public abstract Foo getFoo();
}
public static void main(String[] args) {
for (Foo f : Foo.values()) {
System.out.println(f + " bar " + f.getBar());
}
for (Bar b : Bar.values()) {
System.out.println(b + " foo " + b.getFoo());
}
}
}
上面的代码产生你想要的输出:
A bar Alpha
B bar Delta
C bar Alpha
Alpha foo A
Beta foo C
Delta foo C
也可以看看:
- 覆盖特定枚举的方法 https://stackoverflow.com/a/8615538/1064325
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)