Java Énumérations: Deux types d'énumérations, chacun contenant des références à l'autre?

Est-il un moyen de contourner la classe de chargement de problèmes causés par le fait d'avoir deux énumérations que font référence les uns aux autres?

J'ai deux séries d'énumérations, Foo et Bar, définis comme suit:

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

Le code ci-dessus produit en sortie:

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

Je comprends pourquoi cela arrive - la JVM commence classloading Foo; il voit la Barre.Alpha Foo.Un constructeur, donc il commence à classloading Bar. Il voit le Foo.Une référence dans l'appel à la Barre.Alpha du constructeur, mais (puisque nous sommes encore dans Foo.Un constructeur) Foo.Un est nul à ce point, de sorte Barre.Alpha du constructeur reçoit une valeur null. Si j'inverse les deux boucles for (ou autre Barre de référence avant de Foo), les changements de sortie de sorte que la Barre de valeurs sont tout à fait correct, mais Foo valeurs ne sont pas.

Est-il un moyen de contourner ce problème? Je sais que je peux créer un Mappage statique et une Carte statique dans une 3e classe, mais qui se sent assez hackish pour moi. Je pourrais aussi faire du Foo.getBar() et d'un Bar.getFoo() les méthodes qui font référence à l'extérieur de la carte, de sorte qu'il ne serait même pas changer mon interface (les classes, j'ai utiliser des inspecteurs au lieu de champs publics), mais il se sent en quelque sorte impur pour moi.

(Raison pour laquelle je fais cela dans mon système actuel: Foo et Bar représentent les types de messages que 2 applications envoient l'un à l'autre; le Foo.b et d'un Bar.f champs représentent la réponse attendue pour un type donné de message, donc dans mon exemple de code, lorsque app_1 reçoit un Foo.Un, il doit répondre avec un Bar.Alpha et vice-versa.)

Merci d'avance!

InformationsquelleAutor Sbodd | 2009-10-01