为了账号安全,请及时绑定邮箱和手机立即绑定

在地图中使用通用枚举类

在地图中使用通用枚举类

慕姐4208626 2019-04-18 22:15:15
我有一个类名称映射到他们的枚举类,我有一个方法解析一个字符串,就像"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。您希望整个子字符串达到但不包括句点。


查看完整回答
反对 回复 2019-05-15
  • 2 回答
  • 0 关注
  • 508 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信