Java-Enums: Zwei enum-Typen, jeweils mit verweisen auf die jeweils anderen?

Gibt es einen Weg, um die class-loading-Probleme verursacht, indem er zwei Enumerationen, die aufeinander verweisen?

Habe ich zwei Sätze mit Aufzählungen, Foo und Bar definiert wie folgt:

public class EnumTest {

  public enum Foo {
    A(Bar.Alpha),
    B(Bar.Delta),
    C(Bar.Alpha);

    private Foo(Bar b) {
      this.b = b;
    }

    public final Bar b;
  }

  public enum Bar {
    Alpha(Foo.A),
    Beta(Foo.C),
    Delta(Foo.C);

    private Bar(Foo f) {
      this.f = f;
    }

    public final Foo f;
  }

  public static void main (String[] args) {
    for (Foo f: Foo.values()) {
      System.out.println(f + " bar " + f.b);
    }
    for (Bar b: Bar.values()) {
      System.out.println(b + " foo " + b.f);
    }
  }
}

Den oben genannten code erzeugt als Ausgabe:

A bar Alpha
B bar Delta
C bar Alpha
Alpha foo null
Beta foo null
Delta foo null

Verstehe ich, warum es passiert - die JVM startet zum laden von Klassen Foo; er sieht die Bar.Alpha-Foo.Ein Konstruktor, so beginnt es zum laden von Klassen-Bar. Er sieht die Foo.Ein Verweis im Aufruf Bar.Alpha-Konstruktor, aber (da sind wir immer noch in Foo.Ein Konstruktor) Foo.Eine null an dieser Stelle, also Bar.Alpha-Konstruktor übergeben bekommt eine null. Wenn ich Umgekehrt die beiden Schleifen (oder eine andere Referenz-Bar Foo), der Ausgang sich ändert, so dass die Bar die Werte sind alle richtig, aber Foo Werte nicht.

Gibt es eine Möglichkeit dies zu umgehen? Ich weiß, ich kann eine statische Karte, und eine statische Karte, eine 3. Klasse, aber das fühlt sich ziemlich hackish zu mir. Ich könnte auch Foo.getBar() und Bar.getFoo () - Methoden, die sich auf die externe Karte, also es würde nicht sogar mein interface (die eigentlichen Klassen, die ich habe, verwenden die Inspektoren statt von den öffentlichen Bereichen), aber es fühlt sich immer noch irgendwie unrein zu mir.

(Der Grund, warum ich das hier mache, in meinem aktuellen system: Foo und Bar repräsentieren Arten von Nachrichten, die 2 apps an einander senden; Foo.b und Bar.f Felder repräsentieren die erwartete Reaktion-Typ für eine gegebene Nachricht - also in meinem Beispiel-code, wenn app_1 erhält ein Foo.Eine, die es braucht, um zu Antworten mit einer Bar.Alpha und Umgekehrt.)

Vielen Dank im Voraus!

InformationsquelleAutor Sbodd | 2009-10-01

Schreibe einen Kommentar