【发布时间】:2013-10-17 14:22:11
【问题描述】:
考虑以下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;
}
}
这不会编译,因为 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();
}
虽然实用,但从风格上看,这似乎很恶心。虽然我不知道为什么这会是一个真正的问题。
可能的解决方案 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;
}
}
这比第一个解决方案更严重,因为该字段不再是最终的,并且容易受到反射。归根结底,这是一个晦涩难懂的担忧,但暗示了一种糟糕的代码气味。
有没有办法做到这一点,与第一个示例基本相同,但编译正确?
【问题讨论】:
-
你为什么要列举 Flippables?为什么不直接依次分配每个,因为无论如何您都必须在每个
case:表达式中执行此操作! -
@robert 因为我总是把事情复杂化 :)
标签: java enums self-reference