title: Self referential enum with immutable parameters
body: <p>Consider the following <a href="http://sscce.org">sscce</a></p>
  
  <pre><code>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;
    }
  }
  </code></pre>
  
  <p>This doesn't compile, because <code>Z</code> and <code>Y</code> haven't been declared to be allowed to be arguments of <code>A</code> and <code>B</code>'s constructor.</p>
  
  <p><strong>Potential solution 1:</strong> <em>Hardcoded Methods</em></p>
  
  <pre><code>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();
  }
  </code></pre>
  
  <p>While functional, this seems stylistically quite gross. Though I can't put a finger on why this would be a real problem.</p>
  
  <p><strong>Potential solution 2:</strong> <em>static loading</em></p>
  
  <pre><code>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;
    }
  }
  </code></pre>
  
  <p>This is even more gross than the first solution, as the field is no longer final, and is vulnerable to reflection. Ultimately that is an obscure worry, but suggests a bad code smell.</p>
  
  <p><strong>Is there a way to do this that is essentially the same as the first example, but compiles properly?</strong></p>