我有几个帮助器方法,可以将枚举值转换为适合通过HTML <select>
元素显示的字符串列表。我想知道是否有可能将这些重构为一个单一的多态方法。
这是我现有方法之一的一个示例:
/**
* Gets the list of available colours.
*
* @return the list of available colours
*/
public static List<String> getColours() {
List<String> colours = new ArrayList<String>();
for (Colour colour : Colour.values()) {
colours.add(colour.getDisplayValue());
}
return colours;
}
我对Java泛型仍然很陌生,所以我不确定如何将泛型枚举传递给该方法并在for循环中使用它。
注意,我知道有问题的枚举都会有那个getDisplayValue
方法,但不幸的是,它们没有共享一个定义它的公共类型(我也不能介绍一个),所以我猜它将不得不被反射地访问...?
提前感谢您的帮助。
发布于 2009-08-11 16:06:02
使用Class#getEnumConstants()很简单:
static <T extends Enum<T>> List<String> toStringList(Class<T> clz) {
try {
List<String> res = new LinkedList<String>();
Method getDisplayValue = clz.getMethod("getDisplayValue");
for (Object e : clz.getEnumConstants()) {
res.add((String) getDisplayValue.invoke(e));
}
return res;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
这并不是完全的类型安全,因为你可以有一个没有getDisplayValue
方法的枚举。
发布于 2009-08-11 16:02:22
您可以将此方法放在某个实用程序类中:
public static <T extends Enum<T>> List<String> getDisplayValues(Class<T> enumClass) {
try {
T[] items = enumClass.getEnumConstants();
Method accessor = enumClass.getMethod("getDisplayValue");
ArrayList<String> names = new ArrayList<String>(items.length);
for (T item : items)
names.add(accessor.invoke(item).toString()));
return names;
} catch (NoSuchMethodException ex) {
// Didn't actually implement getDisplayValue().
} catch (InvocationTargetException ex) {
// getDisplayValue() threw an exception.
}
}
发布于 2009-08-11 16:34:01
这种方法避免了反射:
public static interface Displayer<T> {
String displayName(T t);
}
public static <T> List<String> getDisplayNames(Iterable<? extends T> stuff,
Displayer<T> displayer) {
List<String> list = new ArrayList<String>();
for (T t : stuff) {
list.add(displayer.displayName(t));
}
return list;
}
对于您想要显示的所有内容,...but确实需要单独的类型:
enum Foo {
BAR("BAR"), BAZ("BAZ");
private final String displayName;
private Foo(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
}
public static void main(String[] args) {
Displayer<Foo> fooDisplayer = new Displayer<Foo>() {
public String displayName(Foo foo) {
return foo.getDisplayName();
}
};
System.out.println(getDisplayNames(Arrays.asList(Foo.BAR, Foo.BAZ),
fooDisplayer));
}
在这种情况下,使用匿名类型,但它可以是无状态单例或诸如此类的类型。
https://stackoverflow.com/questions/1261233
复制相似问题