Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用';价值';抛出RuntimeException-改用什么?_Java_Enums - Fatal编程技术网

Java 使用';价值';抛出RuntimeException-改用什么?

Java 使用';价值';抛出RuntimeException-改用什么?,java,enums,Java,Enums,我有下面的枚举 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.

我有下面的枚举

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”)以查找特定的动物。但是,我不知道如果没有找到匹配项,就会抛出一个
IllegalArgumentException
。我想可能返回了空值。这给了我一个问题。如果找不到匹配项,我不想捕获此
非法argumentexception
。我希望能够搜索
哺乳动物
类型的所有枚举,并且我不希望必须为
哺乳动物
类型的每个枚举实现此静态“
findMammal
”。所以我的问题是,实施这种行为的最吉祥的设计决策是什么?我将有如下调用代码:

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
   }
}
Animal a = valueOf(Animal.values(), "CAT");

正如你所看到的,我有不同类型的哺乳动物-‘动物’、‘人类’,它们是枚举。我不想为每个哺乳动物枚举实现“findMammal”。我想最好的办法就是创建一个实用类,它接受一个哺乳动物参数并搜索它?也许有更整洁的解决办法

创建一个
HashMap
怎么样?你只需要做一次

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);
  }
}
公共类Foo{
私有静态最终地图名称到哺乳动物地图;
静止的{
NAME_TO_哺乳动物_MAP=new HashMap();
for(Human-Human:EnumSet.allOf(Human.class)){
NAME_TO_哺乳动物_MAP.put(human.NAME(),human);
}
for(动物:EnumSet.allOf(动物类)){
NAME_TO_哺乳动物地图.put(animal.NAME(),animal);
}
}
公共静态哺乳动物栏(最终字符串arg){
将名称返回给哺乳动物映射.get(arg);
}
}
注:

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

      m = Animal.findMammal("CAT");
      
      为什么你不能说

      m = Animal.CAT;
      
      “CAT”无论如何都必须与枚举名匹配,在您的示例中,“CAT”不是从参数派生的,而是硬编码的

      更新 (也许更切题)

      这有点复杂,但是

      public interface Mammal{
      
          public void doMammalStuff();
      
          public static interface Finder{
              public Mammal find(String name, Class<Enum<?>> enumType);
          }
      
          public static Finder FINDER = new Finder(){
              public Mammal find(String name, Class<Enum<?>> enumType) {
                  return enumType.forName( name );
          };
          };
      }
      

      find()的实现可能看起来有所不同(即不引发异常)。

      如果不想触及每个枚举(可以理解),那么实用程序方法就是一种方法。我理解您不想在代码中捕获异常,但在方法中捕获异常应该可以:

      public static <T extends Enum<T>> T findEnumValue(Class<T> type, String name) {
          if (name == null)
              return null;
          try {
              return Enum.valueOf(type, name.toUpperCase());
          } catch (IllegalArgumentException iae) {
              return null;
          }
      }
      
      publicstatict findEnumValue(类类型、字符串名称){
      if(name==null)
      返回null;
      试一试{
      返回Enum.valueOf(type,name.toUpperCase());
      }捕获(IllegalArgumentException iae){
      返回null;
      }
      }
      
      您的代码中有一个错误。如果您需要函数在找不到内容时返回null,只需返回它:

      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;
               }
            }
            return null; // this line works if nothing is found.
         }
      }
      
      如果你犯同样的错误,忘记为每一种可能的情况创建一些返回值,那么任何技术都不会有帮助


      选择:Enum-EnumMaps-HashMap取决于数据的动态。无法在运行时创建枚举常量。另一方面,您不需要在运行时检查很多事情——编译器将完成这项工作。你很可能会忘记检查一些东西。乔恩·斯基特轻松处理的事情可能会让你头疼。

      你可以使用番石榴图书馆。类允许这样做:

      Enums.valueOfFunction(MyEnum.class).apply(id);
      

      我不明白这个问题,但我还需要一个
      valueOf
      ,它返回
      null
      ,而不是抛出异常,因此我创建了这个实用方法:

      public static <T extends Enum<T>> T valueOf(T[] values, String name)
      {
          for (T value : values) {
              if (value.name().equals(name)) {
                  return value;
              }
          }
          return null;
      }
      
      您可以在apache库中使用vom方法。如果未找到,则返回枚举或
      null

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

      你说你不想捕捉异常,为什么?当类型不存在时,您将如何处理该情况?因为这是一个运行时异常,捕获运行时异常是一个主要的禁忌。这就是我的困境
      Animal implements Madama
      ?这不应该是另一种方式吗?哺乳动物是动物的一个亚类……不,它们不是。鳄鱼是动物,但不是哺乳动物。@Joeblackdev:这种笼统的规则正在给你带来不必要的挫折
      parseInt()
      抛出运行时异常,但这并不意味着我在验证用户输入时不应该捕获它。这就是为什么我问你打算如何使用它。如果您经常遇到找不到结果的情况,则抛出异常与返回null无异。这只是表明没有找到匹配项,您需要正确处理这种情况。您能详细介绍一下hashmap方法吗?ThanksHuman.values()几乎等于EnumSet.allOf(Human.class),可以在foreach循环中使用。我应该详细说明一下。我道歉。提供给Animal.findMammal的参数是动态的。我为布莱维特硬编码了,我想是的。我的编辑显示了一个将find实现绑定到接口的版本(不需要知道实现它的枚举类型)。我希望避免捕获运行时异常。我只是不喜欢这样做。如果你真的不想捕获运行时异常(老实说,这看起来很随意),你可以搜索值,或者使用一个后备映射-类似于Jon的答案,但自动填充,不限于动物枚举。似乎被删除了,可能是为了
      enums.getIfPresent(Country.class,countryInput)或(Country.DEFAULT);
      ,这很好。链接仍然可以。因为
      Enum
      变量在Java中可以是
      null
      Enums.getIfPresent(Country.class,countryInput).orNull();
      也很有用。
      EnumUtils.getEnum(Animal.class, "CAT");