使用'valueOf'检索枚举会引发 RuntimeException - 用什么代替?

2022-09-04 05:17:07

我有以下枚举

enum Animal implements Mammal {
   CAT, DOG;

   public static Mammal findMammal(final String type) {
      for (Animal a : Animal.values()) {
         if (a.name().equals(type)) {
            return a;
         }
      }
   }
}

我最初使用它来寻找特定的动物。但是,我不知道如果找不到匹配项,则会抛出一个。我想也许返回了一个空值。所以这给了我一个问题。如果找不到匹配项,我不想抓住这一点。我希望能够搜索类型的所有枚举,并且我不想为类型的每个枚举实现此静态“”。所以我的问题是,实现这种行为的最吉利的设计决策是什么?我将有这样的调用代码:Enum.valueOf(Animal.class, "DOG");IllegalArgumentExceptionIllegalArgumentExceptionMammalfindMammalMammal

public class Foo {
   public Mammal bar(final String arg) {
      Mammal m = null;
      if (arg.equals("SomeValue")) {
         m = Animal.findMammal("CAT");
      } else if (arg.equals("AnotherValue") {
         m = Human.findMammal("BILL");
      }
      // ... etc
   }
}

正如你所看到的,我有不同类型的哺乳动物 - “动物”,“人类”,这些都是枚举。我不想为每个哺乳动物枚举实现“findMammal”。我想最好的办法是创建一个效用类,它采用哺乳动物参数并搜索它?也许有一个更整洁的解决方案。


答案 1

您可以使用 getEnum Method vom the apache EnumUtils 库。它返回枚举,如果未找到,则返回枚举。null

EnumUtils.getEnum(Animal.class, "CAT");

答案 2

如何创建一个 ?你只需要做一次...HashMap<String, Mammal>

public class Foo {

  private static final Map<String, Mammal> NAME_TO_MAMMAL_MAP;

  static {
    NAME_TO_MAMMAL_MAP = new HashMap<String, Mammal>();
    for (Human human : EnumSet.allOf(Human.class)) {
      NAME_TO_MAMMAL_MAP.put(human.name(), human);
    }
    for (Animal animal : EnumSet.allOf(Animal.class)) {
      NAME_TO_MAMMAL_MAP.put(animal.name(), animal);
    }
  }

  public static Mammal bar(final String arg) {
    return NAME_TO_MAMMAL_MAP.get(arg);
  }
}

笔记:

  • 如果名称不存在,这将返回null
  • 这不会检测到名称冲突
  • 您可能希望使用某些描述的不可变映射(例如,通过番石榴)
  • 您可能希望编写一个实用程序方法来为常规枚举创建不可变的名称到值映射,然后只需合并映射:)