Я пытаюсь найти способ перебирать значения перечисления при использовании шаблонов. Не уверен, как это сделать или если это возможно.
Следующий код иллюстрирует то, что я хочу сделать. Обратите внимание, что код T.values () недопустим в следующем коде.
public class Filter<T> {
private List<T> availableOptions = new ArrayList<T>();
private T selectedOption;
public Filter(T selectedOption) {
this.selectedOption = selectedOption;
for (T option : T.values()) { // INVALID CODE
availableOptions.add(option);
}
}
}
Вот как я могу создать экземпляр объекта Filter:
Filter<TimePeriod> filter = new Filter<TimePeriod>(TimePeriod.ALL);
Перечисление определяется следующим образом:
public enum TimePeriod {
ALL("All"),
FUTURE("Future"),
NEXT7DAYS("Next 7 Days"),
NEXT14DAYS("Next 14 Days"),
NEXT30DAYS("Next 30 Days"),
PAST("Past"),
LAST7DAYS("Last 7 Days"),
LAST14DAYS("Last 14 Days"),
LAST30DAYS("Last 30 Days");
private final String name;
private TimePeriod(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
Я понимаю, что может не иметь смысла копировать значения перечисления в список, но я использую библиотеку, которая нуждается в списке значений в качестве входных данных и не будет работать с перечислениями.
РЕДАКТИРОВАТЬ 2/5/2010:
Большинство предложенных ответов очень похожи и предлагают сделать что-то вроде этого:
class Filter<T extends Enum<T>> {
private List<T> availableOptions = new ArrayList<T>();
private T selectedOption;
public Filter(T selectedOption) {
Class<T> clazz = (Class<T>) selectedOption.getClass();
for (T option : clazz.getEnumConstants()) {
availableOptions.add(option);
}
}
}
Это будет прекрасно работать, если я буду уверен, что selectedOption имеет ненулевое значение. К сожалению, в моем случае использования это значение часто равно нулю, так как есть также конструктор public Filter () без аргументов. Это означает, что я не могу сделать selectedOption.getClass () без получения NPE. Этот класс фильтра управляет списком доступных опций, какая из опций выбрана. Если ничего не выбрано, selectedOption имеет значение null.
Единственное, что я могу подумать, чтобы решить эту проблему, это на самом деле передать класс в конструкторе. Вот как то так:
class Filter<T extends Enum<T>> {
private List<T> availableOptions = new ArrayList<T>();
private T selectedOption;
public Filter(Class<T> clazz) {
this(clazz,null);
}
public Filter(Class<T> clazz, T selectedOption) {
this.selectedOption = selectedOption;
for (T option : clazz.getEnumConstants()) {
availableOptions.add(option);
}
}
}
Есть какие-нибудь идеи, как сделать это без необходимости использования дополнительного параметра Class в конструкторах?