在地图中使用通用枚举类

我有一个类名称映射到他们的枚举类,我有一个方法解析一个字符串,就像"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,它将无法编译,但警告消失。周围有好的方法吗?


慕姐4208626
浏览 509回答 2
2回答

慕勒3428872

没有安全的方法来获得其泛型类型取决于相应键的Map值。但是,您可以自己存储枚举常量:private&nbsp;static&nbsp;final&nbsp;Map<String,&nbsp;Map<String,&nbsp;?>>&nbsp;enumsMap;static&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;enumsMap&nbsp;=&nbsp;new&nbsp;HashMap<>(); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;These&nbsp;are&nbsp;two&nbsp;DIFFERENT&nbsp;enum&nbsp;classes! &nbsp;&nbsp;&nbsp;&nbsp;registerEnum(SomeEnum.class); &nbsp;&nbsp;&nbsp;&nbsp;registerEnum(AnotherEnum.class);}private&nbsp;static&nbsp;<T&nbsp;extends&nbsp;Enum<T>>&nbsp;void&nbsp;registerEnum(Class<T>&nbsp;enumClass)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;Map<String,&nbsp;?>&nbsp;valuesByName&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EnumSet.allOf(enumClass).stream().collect( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collectors.toMap(Enum::name,&nbsp;Function.identity())); &nbsp;&nbsp;&nbsp;&nbsp;enumsMap.put(enumClass.getSimpleName(),&nbsp;valuesByName);}public&nbsp;Object[]&nbsp;parse(List<String>&nbsp;strParameters)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;Object[]&nbsp;parameters&nbsp;=&nbsp;new&nbsp;Object[strParameters.size()]; &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;parameters.length;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;strParameter&nbsp;=&nbsp;strParameters.get(i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;delim&nbsp;=&nbsp;strParameter.lastIndexOf('.'); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;className&nbsp;=&nbsp;strParameter.substring(0,&nbsp;delim); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;enumName&nbsp;=&nbsp;strParameter.substring(delim&nbsp;+&nbsp;1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map<String,&nbsp;?>&nbsp;enumValues&nbsp;=&nbsp;enumsMap.get(className); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parameters[i]&nbsp;=&nbsp;enumValues.get(enumName); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(parameters[i]&nbsp;==&nbsp;null)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;IllegalArgumentException("Class&nbsp;"&nbsp;+&nbsp;className&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;"&nbsp;does&nbsp;not&nbsp;contain&nbsp;constant&nbsp;"&nbsp;+&nbsp;enumName); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;parameters;}我改变了什么:enumsMap现在Map<String, Map<String, ?>>。每个值都是由常量名称键入的枚举常量的Map。&nbsp;?足够了;&nbsp;因为parse返回,所以记住常量值是枚举是没有好处的Object[]。registerEnum具有泛型类型,以保证其参数是有效的枚举类型。它不存储类参数,而是存储枚举的常量。parse不需要泛型类型,因为它返回Object[]。parse&nbsp;不使用Enum的任何方法,因此通用类型安全不再是一个问题。我修正了一个错误:&nbsp;strParameter.substring(0, delim);而不是delim - 1。您希望整个子字符串达到但不包括句点。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java