Java枚举 - 在定义字段之前无法引用该字段

Zaq*_*Zaq 8 java enums

我有一个类似下面的枚举,但是eclipse说每对对方的第一个定义都有错误.

public enum Baz{
  yin(yang),    //Cannot reference a field before it is defined
  yang(yin),
  good(evil),   //Cannot reference a field before it is defined
  evil(good);

  public final Baz opposite;

  Baz(Baz opposite){
    this.opposite = opposite;
  }
}
Run Code Online (Sandbox Code Playgroud)

我想要完成的是能够Baz.something.opposite用来获得相反的对象Baz.something.这有可能的解决方法吗?也许对于一个空的占位符yangbad之前yingood在此示例中定义的?

mer*_*ike 12

使用switch语句:

public enum Baz{
  yin,
  yang,
  good,
  evil;

  public Baz getOpposite() {
    switch (this) {
        case yin: return yang;
        case yang: return yin;
        case good: return evil;
        case evil: return good;
    }
    throw new AssertionError();
}
Run Code Online (Sandbox Code Playgroud)

或者延迟初始化:

public enum Baz{
  yin,
  yang,
  good,
  evil;

  public Baz opposite;

  static {
    yin.opposite = yang;
    yang.opposite = yin;
    good.opposite = evil;
    evil.opposite = good;
  }
}
Run Code Online (Sandbox Code Playgroud)

您可能希望将可变字段设为私有并提供getter.

  • +1为您的第二个建议。讨厌`switch`的想法。 (2认同)

jce*_*ern 11

你可以尝试类似的东西:

public enum Baz{
  yin("yang"),    
  yang("yin"),
  good("evil"),   
  evil("good");

  private String opposite;

  Baz(String opposite){
    this.opposite = opposite;
  }

  public Baz getOpposite(){
     return Baz.valueOf(opposite);
  }
}
Run Code Online (Sandbox Code Playgroud)

然后将其引用为

Baz.something.getOpposite()
Run Code Online (Sandbox Code Playgroud)

这应该通过它的字符串表示查找枚举值来完成你想要做的事情.我不认为你能用它来处理Baz的递归引用.

  • 用无类型的字符串替换有类型的枚举值不是一个好的解决方案。枚举的全部要点是为常量提供类型安全性,而字符串则没有。此外,还有更好的解决方案-在@meriton的答案中指出,在静态初始化程序块中执行此操作。 (2认同)