我有一个类名称映射到他们的枚举类,我有一个方法解析一个字符串,就像"SomeEnum.FIRST"实际的对象。但是当地图无法存储时Enum.valueOf不接受。Class<? extends Enum<?>>Class<T extends Enum<T>>对于代码,地图看起来像这样: private static final HashMap<String, Class<? extends Enum<?>>> enumsMap;
static {
enumsMap = new HashMap<>();
// These are two DIFFERENT enum classes!
registerEnum(SomeEnum.class);
registerEnum(AnotherEnum.class);
}
private static void registerEnum(Class<? extends Enum<?>> enumClass) {
enumsMap.put(enumClass.getSimpleName(), enumClass);
}这是解析器(删除不必要的代码): public <T extends Enum<T>> Object[] parse(List<String> strParameters) {
Object[] parameters = new Object[strParameters.size()];
for (int i = 0; i < parameters.length; i++) {
String strParameter = strParameters.get(i);
int delim = strParameter.lastIndexOf('.');
String className = strParameter.substring(0, delim - 1);
String enumName = strParameter.substring(delim + 1);
Class<T> enumClass = (Class<T>) enumsMap.get(className);
parameters[i] = Enum.valueOf(enumClass, enumName);
}
return parameters;
}现在,如果我这样称呼parse,我的IDE(Android Studio)告诉我,“未经检查的方法”解析(List)'调用',并且这是因为该泛型类型。如果我删除它parse,它将无法编译,但警告消失。周围有好的方法吗?
2 回答
慕勒3428872
TA贡献1848条经验 获得超6个赞
没有安全的方法来获得其泛型类型取决于相应键的Map值。
但是,您可以自己存储枚举常量:
private static final Map<String, Map<String, ?>> enumsMap;static { enumsMap = new HashMap<>(); // These are two DIFFERENT enum classes! registerEnum(SomeEnum.class); registerEnum(AnotherEnum.class);}private static <T extends Enum<T>> void registerEnum(Class<T> enumClass) { Map<String, ?> valuesByName = EnumSet.allOf(enumClass).stream().collect( Collectors.toMap(Enum::name, Function.identity())); enumsMap.put(enumClass.getSimpleName(), valuesByName);}public Object[] parse(List<String> strParameters) { Object[] parameters = new Object[strParameters.size()]; for (int i = 0; i < parameters.length; i++) { String strParameter = strParameters.get(i); int delim = strParameter.lastIndexOf('.'); String className = strParameter.substring(0, delim); String enumName = strParameter.substring(delim + 1); Map<String, ?> enumValues = enumsMap.get(className); parameters[i] = enumValues.get(enumName); if (parameters[i] == null) { throw new IllegalArgumentException("Class " + className + " does not contain constant " + enumName); } } return parameters;}
我改变了什么:
enumsMap
现在Map<String, Map<String, ?>>
。每个值都是由常量名称键入的枚举常量的Map。?
足够了; 因为parse
返回,所以记住常量值是枚举是没有好处的Object[]
。registerEnum
具有泛型类型,以保证其参数是有效的枚举类型。它不存储类参数,而是存储枚举的常量。parse
不需要泛型类型,因为它返回Object[]
。parse
不使用Enum的任何方法,因此通用类型安全不再是一个问题。我修正了一个错误:
strParameter.substring(0, delim);
而不是delim - 1
。您希望整个子字符串达到但不包括句点。
添加回答
举报
0/150
提交
取消