Це означає, що аргумент типу для enum має випливати з enum, який сам має аргумент того ж типу. Як це може статися? Зробивши аргумент типу самим новим типом. Отже, якщо у мене є перелік під назвою StatusCode, це було б рівнозначно:
public class StatusCode extends Enum<StatusCode>
Тепер якщо ви перевірите обмеження, у нас є Enum<StatusCode>
- так E=StatusCode
. Давайте перевіримо: чи E
поширюєтьсяEnum<StatusCode>
? Так! Ми все в порядку.
Ви, можливо, запитаєте себе, в чому суть цього :) Ну, це означає, що API для Enum може посилатися на себе - наприклад, бути в змозі сказати, що Enum<E>
реалізує Comparable<E>
. Базовий клас здатний проводити порівняння (у разі перерахунків), але він може переконатися, що він лише порівнює правильний вид перерахунків між собою. (EDIT: Ну, майже - дивіться правки внизу.)
Я використовував щось подібне в моєму C # порту ProtocolBuffers. Існують "повідомлення" (незмінні) та "будівельники" (мутабельні, використовуються для створення повідомлення) - і вони надходять як пари типів. Задіяні інтерфейси:
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>
Це означає, що з повідомлення ви можете отримати відповідного конструктора (наприклад, взяти копію повідомлення і змінити деякі біти), а від конструктора ви зможете отримати відповідне повідомлення, коли закінчите його створювати. Корисним робочим користувачам API не потрібно насправді дбати про це - це жахливо складно, і потрібно було кілька ітерацій, щоб дістатися до місця, де він є.
EDIT: Зауважте, що це не заважає вам створювати непарні типи, які використовують аргумент типу, який сам по собі є нормальним, але який не є тим самим. Метою є надання переваг у правильному випадку, а не захист від неправильної справи.
Тож якби Enum
до Java все-таки не зверталися "спеціально", ви могли (як зазначено в коментарях) створити такі типи:
public class First extends Enum<First> {}
public class Second extends Enum<First> {}
Second
буде реалізовуватись, Comparable<First>
а не Comparable<Second>
... але First
сама була б добре.