Dies bedeutet, dass das Typargument für enum von einer Aufzählung abgeleitet werden muss, die selbst dasselbe Typargument hat. Wie kann das passieren? Indem Sie das Typargument zum neuen Typ selbst machen. Wenn ich also eine Aufzählung mit dem Namen StatusCode habe, entspricht dies:
public class StatusCode extends Enum<StatusCode>
Wenn Sie nun die Einschränkungen überprüfen, haben wir Enum<StatusCode>
- also E=StatusCode
. Lassen Sie uns überprüfen: E
verlängert Enum<StatusCode>
? Ja! Wir sind okay.
Sie fragen sich vielleicht, worum es geht :) Nun, das bedeutet, dass die API für Enum auf sich selbst verweisen kann - zum Beispiel, wenn Sie sagen können, dass dies Enum<E>
implementiert ist Comparable<E>
. Die Basisklasse kann die Vergleiche durchführen (im Fall von Aufzählungen), aber sie kann sicherstellen, dass nur die richtige Art von Aufzählungen miteinander verglichen wird. (EDIT: Nun, fast - siehe die Bearbeitung unten.)
Ich habe etwas Ähnliches in meinem C # -Port von ProtocolBuffers verwendet. Es gibt "Nachrichten" (unveränderlich) und "Builder" (veränderlich, zum Erstellen einer Nachricht verwendet) - und sie kommen als Typenpaare. Die beteiligten Schnittstellen sind:
public interface IBuilder<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
public interface IMessage<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
Dies bedeutet, dass Sie aus einer Nachricht einen geeigneten Builder erhalten können (z. B. um eine Kopie einer Nachricht zu erstellen und einige Bits zu ändern), und von einem Builder können Sie eine entsprechende Nachricht erhalten, wenn Sie mit dem Erstellen fertig sind. Es ist ein guter Job, den Benutzer der API nicht wirklich interessieren müssen - es ist schrecklich kompliziert und es dauerte mehrere Iterationen, um dorthin zu gelangen, wo es ist.
BEARBEITEN: Beachten Sie, dass dies Sie nicht davon abhält, ungerade Typen zu erstellen, die ein Typargument verwenden, das selbst in Ordnung ist, aber nicht vom selben Typ ist. Der Zweck besteht darin, Vorteile im richtigen Fall zu bieten, anstatt Sie vor dem falschen Fall zu schützen .
Wenn Enum
Sie also in Java sowieso nicht "speziell" behandelt würden, könnten Sie (wie in den Kommentaren angegeben) die folgenden Typen erstellen:
public class First extends Enum<First> {}
public class Second extends Enum<First> {}
Second
würde Comparable<First>
eher implementieren als Comparable<Second>
... aber First
selbst wäre in Ordnung.