将Generic与Enum一起使用时遇到了一些问题:
enum MyEnum1 {
// ...
public static MyEnum fromString(String enumStr) { /* ... */ }
}
enum MyEnum2 {
// ...
public static MyEnum fromString(String enumStr) { /* ... */ }
}
enum MyEnum3 {
// ...
public static MyEnum fromString(String enumStr) { /* ... */ }
}
class MyClass {
Map<Class<? extends Enum<?>, EnumSet<? extends Enum<?>>> map;
public <E extends Enum<E>> void addValue2EnumSet(Class<E> enumType, E value);
// enumType and valueStr is of the same length
public static Map<Class<? extends Enum<?>, EnumSet<? extends Enum<?>>> getMapOfEnumSet(Class<? extends Enum<?>>[] enumTypes, String[] valueStrs) {
MyClass c = // ...
for (int i = 0; i < enumTypes.length; ++i) {
// for each enumType and valueStr pair
// add the value (= Enum1/2/3.fromString(valueStr)) to the Map
Class<? extends Enum<?>> enumType = enumTypes[i];
String valueStr = valueStrs[i];
Method fromStringMethod = enumType.getDeclaredMethod("fromString", String.class);
// error!
c.addValue2EnumSet(enumType, enumType.cast(fromStringMethod.invoke(null, valueStr)));
}
return c.map;
}
}
在这一行c.addValue2EnumSet(enumType, enumType(fromStringMethod.invoke(null, valueStr)));
中,编译错误是第二个参数Found: 'java.lang.Enum<?>
,必需:'?扩展java.lang.Enum'`
如何在addValue2EnumSet()
中致电getEnumSetOf()
?
在这种情况下,传递Class<? extends Enum<?> enumType
参数,它用于判断哪种Enum(Enum1 / 2/3)是目标,然后调用fromString()
方法生成相应的Enum实例。我不知道从enumType获取方法的反射。
困难的是getEnumSetOf
的两个参数是数组,第一个参数中的每个元素,例如enumTypes[0]
,选择相应的第二个参数的枚举类型,例如{{1} }。也就是说,valueStrs[0]
的目标类型是valueStrs[0]
。
答案 0 :(得分:1)
不太确定为什么使用泛型 - 也许你可以进一步解释。
假设您想通过字符串名称从种子构建枚举集,您可能会发现此技术可用。其中关键部分是使用Enum.getDeclaringClass()方法。
enum ABEnum {
A, B;
public static ABEnum fromString(String enumStr) {
return ABEnum.valueOf(enumStr);
}
}
public static Enum fromString(Enum seed, String enumStr) throws Exception {
Class declaringClass = seed.getDeclaringClass();
Method fromStringMethod = declaringClass.getDeclaredMethod("fromString", String.class);
Object result = fromStringMethod.invoke(null, enumStr);
return (Enum) result;
}
public void test() throws Exception {
Enum e = fromString(ABEnum.A, "B");
System.out.println(e);
}
这似乎更适合您的场景 - 它通过反射构建一个与您的地图非常相似的地图。也许它会有所帮助。
enum ABEnum {
A, B, E;
public static ABEnum fromString(String enumStr) {
return ABEnum.valueOf(enumStr);
}
}
enum CDEnum {
C, D, E;
public static CDEnum fromString(String enumStr) {
return CDEnum.valueOf(enumStr);
}
}
public static Enum fromString(Enum seed, String enumStr) throws Exception {
Class declaringClass = seed.getDeclaringClass();
Method fromStringMethod = declaringClass.getDeclaredMethod("fromString", String.class);
Object result;
try {
result = fromStringMethod.invoke(null, enumStr);
} catch (InvocationTargetException e) {
result = null;
}
return (Enum) result;
}
Map<Class, EnumSet> map = new HashMap<>();
public void test() throws Exception {
//Enum e = fromString(ABEnum.A, "B");
Enum[] enums = new Enum[]{ABEnum.A, CDEnum.C};
String[] names = new String[]{"A", "B", "C", "D", "E"};
for (Enum e : enums) {
Class c = e.getClass();
for (String s : names) {
EnumSet set = map.get(c);
if (set == null) {
map.put(c, set = EnumSet.noneOf(c));
}
Enum found = fromString(e, s);
if (found != null) {
set.add(found);
}
}
}
System.out.println(map);
}