Переваги на Java великі. Так само і дженерики. Звичайно, всі ми знаємо обмеження останнього через стирання типу. Але є одне, чого я не розумію. Чому я не можу створити такий перелік:
public enum MyEnum<T> {
LITERAL1<String>,
LITERAL2<Integer>,
LITERAL3<Object>;
}
Цей параметр загального типу <T>
в свою чергу може бути корисним у різних місцях. Уявіть параметр загального типу для методу:
public <T> T getValue(MyEnum<T> param);
Або навіть у самому класі enum:
public T convert(Object o);
Більш конкретний приклад №1
Оскільки вищенаведений приклад для деяких може здатися занадто абстрактним, ось приклад з реального життя, чому я хочу це зробити. У цьому прикладі я хочу використовувати
- Перелічує, бо тоді я можу перерахувати скінченний набір властивостей ключів
- Загальне, тому що тоді я можу забезпечити безпеку типу типу для зберігання властивостей
public interface MyProperties {
public <T> void put(MyEnum<T> key, T value);
public <T> T get(MyEnum<T> key);
}
Більш конкретний приклад №2
У мене перерахування типів даних:
public interface DataType<T> {}
public enum SQLDataType<T> implements DataType<T> {
TINYINT<Byte>,
SMALLINT<Short>,
INT<Integer>,
BIGINT<Long>,
CLOB<String>,
VARCHAR<String>,
...
}
Кожен переслідник перерахунку очевидно мав би додаткові властивості, засновані на родовому типі <T>
, в той же час, будучи перерахунком (незмінним, синглетним, перелічуючим тощо) тощо.
Питання:
Ніхто про це не думав? Це обмеження щодо компілятора? Враховуючи той факт, що ключове слово " enum " реалізовано як синтаксичний цукор, що представляє згенерований код JVM, я не розумію цього обмеження.
Хто може мені це пояснити? Перш ніж відповісти, подумайте про це:
- Я знаю, що родові типи стираються :-)
- Я знаю, що існують обхідні шляхи використання об’єктів Class. Вони обхідні шляхи.
- Загальні типи призводять до того, що вони генеруються компілятором, коли вони застосовуються (наприклад, при виклику методу convert ()
- Родовий тип <T> був би на перерахунку. Отже, він пов'язаний кожним із буквалів перерахунку. Отже, компілятор буде знати, який тип застосувати, коли пише щось подібне
String string = LITERAL1.convert(myObject); Integer integer = LITERAL2.convert(myObject);
- Це ж стосується параметра загального типу в
T getvalue()
методі. Компілятор може застосовувати кастинг типів під час викликуString string = someClass.getValue(LITERAL1)
enum
ідіому "typesafe enum", яку ми використовували до Java 1.5. Раптом у вас можуть бути налаштовані параметри членів перерахунку. Це, мабуть, те, що я зараз буду робити.