我有一个类名称映射到他们的枚举类,我有一个方法解析一个字符串,就像"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
提交
取消
