Tôi đang cố gắng tìm cách lặp lại các giá trị của enum trong khi sử dụng generic. Không chắc chắn về cách thực hiện điều này hoặc nếu có thể.
Đoạn mã sau minh họa những gì tôi muốn làm. Lưu ý rằng mã T.values () không hợp lệ trong đoạn mã sau.
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);
}
}
}
Đây là cách tôi khởi tạo đối tượng Bộ lọc:
Filter<TimePeriod> filter = new Filter<TimePeriod>(TimePeriod.ALL);
Enum được định nghĩa như sau:
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;
}
}
Tôi nhận thấy có thể không hợp lý khi sao chép các giá trị của enum vào một danh sách, nhưng tôi đang sử dụng một thư viện cần danh sách các giá trị làm đầu vào và sẽ không hoạt động với enum.
CHỈNH SỬA 2/5/2010:
Hầu hết các câu trả lời được đề xuất đều rất giống nhau và bạn nên làm như sau:
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);
}
}
}
Điều này sẽ hoạt động tốt nếu tôi có thể chắc chắn rằng selectOption có giá trị khác rỗng. Thật không may, trong trường hợp sử dụng của tôi, giá trị này thường là null, vì cũng có một phương thức khởi tạo Filter () no-arg công khai. Điều này có nghĩa là tôi không thể thực hiện một selectOption.getClass () mà không nhận được NPE. Lớp bộ lọc này quản lý một danh sách các tùy chọn có sẵn mà các tùy chọn được chọn. Khi không có gì được chọn, tùy chọn đã chọn là trống.
Điều duy nhất tôi có thể nghĩ để giải quyết vấn đề này là thực sự truyền vào một Class trong hàm tạo. Vì vậy, một cái gì đó như thế này:
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);
}
}
}
Bất kỳ ý tưởng nào về cách thực hiện điều này mà không cần tham số Lớp bổ sung trong các hàm tạo?
getClass
mã cũng sẽ thất bại nếu hằng số enum là một lớp con nặc danh ( ví dụ ).getDeclaringClass
nên được sử dụng thay thế.