Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java enum- Cannot reference a field before it is defined

Tags:

java

enums

I have an enum like the one below, but eclipse says that there are errors in the first definition of each opposite pair.

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;
  }
}

What I want to accomplish is being able to use Baz.something.opposite to get the opposite object of Baz.something. Is there a possible workaround for this? Maybe an empty placeholder for yang and bad before yin and good are defined in this example?

like image 985
Zaq Avatar asked Sep 25 '12 22:09

Zaq


3 Answers

You could try something like:

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);
  }
}

and then reference it as

Baz.something.getOpposite()

That should accomplish what you are looking to do by looking up the enum value by it's string representation. I don't think you can get it to work with the recursive reference to Baz.

like image 174
jcern Avatar answered Nov 02 '22 18:11

jcern


With the switch statement:

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();
}

Or deferred initialization:

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

  public Baz opposite;

  static {
    yin.opposite = yang;
    yang.opposite = yin;
    good.opposite = evil;
    evil.opposite = good;
  }
}

You might wish to make the mutable field private and provide a getter.

like image 39
meriton Avatar answered Nov 02 '22 18:11

meriton


How about an EnumMap?

public enum Baz {
  yin,
  yang,
  good,
  evil;
  private static final Map<Baz, Baz> opposites = new EnumMap<Baz, Baz>(Baz.class);

  static {
    opposites.put(yin, yang);
    opposites.put(yang, yin);
    opposites.put(good, evil);
    opposites.put(evil, good);
  }

  public Baz getOpposite() {
    return opposites.get(this);
  }
}
like image 4
OldCurmudgeon Avatar answered Nov 02 '22 20:11

OldCurmudgeon