dur*_*597 9 java enums self-reference
请考虑以下sscce
public enum Flippable
A (Z), B (Y), Y (B), Z (A);
private final Flippable opposite;
private Flippable(Flippable opposite) {
this.opposite = opposite;
}
public Flippable flip() {
return opposite;
}
}
Run Code Online (Sandbox Code Playgroud)
这不会编译,因为Z并且Y还没有被声明被允许作为A和B构造函数的参数.
可能的解决方案1: 硬编码方法
public enum Flippable {
A {
public Flippable flip() { return Z; }
}, B {
public Flippable flip() { return Y; }
}, Y {
public Flippable flip() { return B; }
}, Z {
public Flippable flip() { return A; }
};
public abstract Flippable flip();
}
Run Code Online (Sandbox Code Playgroud)
虽然功能性,但在风格上看起来相当粗糙.虽然我无法理解为什么这会成为一个真正的问题.
潜在解决方案2: 静态加载
public enum Flippable {
A, B, Y, Z;
private Flippable opposite;
static {
for(Flippable f : Flippable.values()) {
switch(f) {
case A:
f.opposite = Z;
break;
case B:
f.opposite = Y;
break;
case Y:
f.opposite = B;
break;
case Z:
f.opposite = A;
break;
}
}
}
public Flippable flip() {
return opposite;
}
}
Run Code Online (Sandbox Code Playgroud)
这比第一个解决方案更加严重,因为该领域不再是最终的,并且易受反射影响.最终这是一个模糊的担忧,但暗示代码味道不好.
有没有办法做到这一点与第一个例子基本相同,但编译正确?
rob*_*ert 13
也许不像你想要的那样漂亮......
public enum Flippable {
A, B, Z, Y;
static {
A.opposite = Z;
B.opposite = Y;
Y.opposite = B;
Z.opposite = A;
}
public Flippable flip() {
return opposite;
}
private Flippable opposite;
public static void main(String[] args) {
for(Flippable f : Flippable.values()) {
System.out.println(f + " flips to " + f.flip());
}
}
}
Run Code Online (Sandbox Code Playgroud)