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");