Próbuję znaleźć sposób na iterację wartości wyliczenia podczas korzystania z typów ogólnych. Nie wiem, jak to zrobić lub czy jest to możliwe.
Poniższy kod ilustruje to, co chcę zrobić. Zauważ, że kod T.values () nie jest prawidłowy w poniższym kodzie.
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);
}
}
}
Oto, jak utworzę instancję obiektu Filter:
Filter<TimePeriod> filter = new Filter<TimePeriod>(TimePeriod.ALL);
Wyliczenie jest zdefiniowane w następujący sposób:
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;
}
}
Zdaję sobie sprawę, że kopiowanie wartości wyliczenia na listę może nie mieć sensu, ale używam biblioteki, która wymaga listy wartości jako danych wejściowych i nie będzie działać z wyliczeniami.
EDYCJA 05.02.2010:
Większość proponowanych odpowiedzi jest bardzo podobnych i sugeruje zrobienie czegoś takiego:
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);
}
}
}
Byłoby to świetnie, gdybym był pewien, że selectedOption ma wartość różną od null. Niestety, w moim przypadku użycia ta wartość jest często zerowa, ponieważ istnieje również publiczny konstruktor Filter () no-arg. Oznacza to, że nie mogę wykonać selectedOption.getClass () bez uzyskania NPE. Ta klasa filtru zarządza listą dostępnych opcji, które z nich są wybrane. Gdy nic nie jest zaznaczone, selectedOption ma wartość null.
Jedyną rzeczą, o której myślę, aby rozwiązać ten problem, jest przekazanie klasy w konstruktorze. Więc coś takiego:
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);
}
}
}
Jakieś pomysły, jak to zrobić bez konieczności dodatkowego parametru Class w konstruktorach?
getClass
Kod będzie również zawieść jeśli stała enum jest anonimowy podklasa ( przykład ).getDeclaringClass
należy użyć zamiast tego.