简体   繁体   English

使用反射将字符串转换为枚举值,其中枚举类型可以是多个

[英]Convert string to enum value using reflection, where the enum type can be any of several

Suppose I have a class that takes another object as an id:假设我有一个 class 以另一个 object 作为 id:

public SomeClass
{
    private final ID id;

    ...
}

ID is then defined as below.然后ID定义如下。 Note that the reason that the enum is split up (into logical groupings) is because a single enum would otherwise contain 1000+ values.请注意,枚举被拆分(分成逻辑分组)的原因是因为单个枚举将包含 1000 多个值。 The interface is then necessary to still have all the enums fall under the same type.然后需要该接口以使所有枚举都属于同一类型。

public interface ID
{
    public enum Name1 implements ID { ... constants ... }
    public enum Name2 implements ID { ... constants ... }
    public enum Name3 implements ID { ... constants ... }

    ...
}

And an object of SomeClass is constructed like so: SomeClass的 object 的构造如下:

SomeClass object = new SomeClass(ID.Name2.SOME_VALUE, ... more parameters};

However, the parameters necessary to construct the SomeClass object are stored in a json file, like so:但是,构造SomeClass object 所需的参数存储在 json 文件中,如下所示:

{
    "id": "SOME_VALUE",

    ...
}

What I want to do is to map the string "SOME_VALUE" to ID.Name2.SOME_VALUE .我想要做的是 map 字符串"SOME_VALUE"ID.Name2.SOME_VALUE Now, I could do this by having a giant map:现在,我可以通过拥有一个巨大的 map 来做到这一点:

Map<String, ID> conversionMap = HashMap<>();
conversionMap.put("SOME_VALUE", ID.Name2.SOME_VALUE);
conversionMap.put("SOME_OTHER_VALUE", ID.Name3.SOME_OTHER_VALUE);
... etc

but I want to do it automatically using reflection from a static method inside the ID interface (some very rough pseudocode):但我想使用来自ID接口内的 static 方法的反射自动执行此操作(一些非常粗略的伪代码):

public interface ID
{
    public static ID getIdFromString(String key)
    {
        List<Enum> declaredEnums = ID.class.getDeclaredEnums();
        for (Enum declaredEnum : declaredEnums)
        {
            for (EnumValue value : declaredEnum)
            {
                if (value.equals(key)
                    return value;
            }
        }
    }

    public enum Name1 implements ID { ... constants ... }
    public enum Name2 implements ID { ... constants ... }
    public enum Name3 implements ID { ... constants ... }

    ...
}

How would I do such a thing?我怎么会做这样的事情? I am getting lost in the reflection here, and having searched through many other questions and answers I still seem to not be any closer to the answer.我在这里的反思中迷失了方向,并且在搜索了许多其他问题和答案之后,我似乎仍然离答案更近了。

Note that I could also implement this using 1000+ integer constants and providing a string > integer mapping for that, but using enums feels cleaner.请注意,我也可以使用 1000+ integer 常量并为此提供一个字符串 > integer 映射来实现这一点,但使用枚举感觉更干净。 Now that I have hit this snag I am not so convinced of the cleanliness anymore though.现在我遇到了这个障碍,但我不再那么相信清洁了。 It is starting to feel like I am trying to fit a round peg into a square hole.我开始觉得我正在尝试将圆形钉子装入方孔中。

UPDATE: I ended up using the accepted answer as the solution and modified it a tiny bit to work with my code:更新:我最终使用接受的答案作为解决方案,并对其进行了一点修改以使用我的代码:

public static ID getIdFromString(String key)
{
    Optional<?> id = Arrays.stream(ID.class.getDeclaredClasses())
        .filter(Class::isEnum)
        .flatMap(aClass -> Arrays.stream(aClass.getEnumConstants()))
        .filter(enumValue -> enumValue.toString().equals(key))
        .findFirst();

        return (ID)id.get();
}

Beware that this code does not do any checking at all, so you should probably add some checks to it to handle invalid keys, and maybe even handle enums that are declared in ID but do not implement the ID interface.请注意,此代码根本不进行任何检查,因此您可能应该对其添加一些检查以处理无效键,甚至可能处理在ID中声明但未实现ID接口的枚举。

You can get all declared classes via reflection (including enums) and do something like this:您可以通过反射(包括枚举)获取所有声明的类并执行以下操作:

 Arrays.stream(getClass().getDeclaredClasses())
      .filter(Class::isEnum)
      .flatMap(aClass -> Arrays.stream(aClass.getEnumConstants()))
      .filter(enumValue -> enumValue.toString().equals(YOUR_VALUE_FROM_JSON))
      .findFirst();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM