使用例外来validation输入

我试图检查用户传递的值是否有效常量。 这是我写的代码。

enum Media_Delivery { Streaming, Progressive } public class TestMain { public static void main(String[] args) { String medi_delivery = "streaming"; try { Media_Delivery.valueOf("streaming"); } catch (IllegalArgumentException e) { System.out.print(e); } } } 

现在,在上面的代码中,如果传递的String没有列出枚举的枚举,那么它会抛出IllegalArgumentException ,这很明显。

但我的问题是:这是validation的正确方法吗? 因为我们正在使用Java的exception机制来validation。

有人可以建议一个更好的想法或我上面编码的是最好的选择吗?

– – -编辑 – – – –

我想讨论的另一个案例:

 public class TestMain { public static void main(String[] args) { String inputPassed = "2a"; try { Integer.parseInt(inputPassed); } catch (NumberFormatException nfe) { throw new SomeUserDefinedException("Please enter only numeric values"); } } 

这是一个好主意吗? 或者应该有我们自己的解析机制?

exception应用于特殊情况 ; 你不希望发生的事情。 validation输入不是很特别。

Josh Bloch实际上在他的“Effective Java”一书中特别概述了这一点,IMHO是每个Java程序员都应该拥有的。

编辑:这实际上是如何解决问题的一个非常好的答案:

在使用枚举之前检查有效的枚举值

通常最好不要捕获或抛出未经检查的表达式( IllegalArgumentException是一个计为“未选中”的RuntimeException )。 有关更多详细信息,请参阅Java教程 – 例外 。 如果可以避免它,请尝试重写代码,以便不需要捕获运行时exception。 这是一个有争议的问题,但运行时exception存在的原因是:它们帮助程序员识别错误。 如果你抓住了它们,那么这个bug就没有得到修复,它只是被避免了。 尝试使用if-else语句?

根据API ,“名称必须完全匹配用于声明枚举常量的标识符。” 我相信这意味着参数区分大小写 。 另外, valueOf方法的返回类型是某种类型,而不是void ,因此您不能在try块中使用该语句。 try块应该包含命令或void方法,例如int x = 3;System.out.println(3); 或者其他的东西。

– – – – 编辑 – – – –

OP,回应你的评论:

像其他人一样,这取决于你想要完成的事情。 我假设你有行Media_Delivery.valueOf("streaming");try块中,你试图看看"streaming"是否等于枚举常量之一? 在这种情况下,你不需要if-else语句,你可以简单地写

 boolean result = medi_delivery.equals(Media_Delivery.Streaming.name()) || medi_delivery.equals(Media_Delivery.Progressive.name()); System.out.println(result); 

或者甚至更好,如果你不想有多个|| 条件,尝试循环遍历每个枚举常量的switch语句,测试给定字符串的相等性。

-克里斯

PS:关于命名约定,因为枚举常量是隐式static final ,所以通常的做法是在所有大写中声明它们,例如STREAMINGPROGRESSIVE ( Java Tutorials – Enums )。

我会说这取决于。

如果输入来自combobox或其他任何内容的GUI元素,其中枚举值是唯一可供选择的 – 那么您的方法就可以了。 在这里,不同的价值实际上是一个例外。

但是如果您正在制作控制台应用程序,或者文本文件可能会输入任何内容,那么结果会有所不同,那么枚举值不应被视为exception。 您应该使用这种方法的正常if-else或case。

通常:仅在特殊情况下使用exception,而不是在真正可能发生的情况下使用exception。

没有单一的“正确”方式来validation,你所拥有的肯定会是我validation的方式,但还有其他方法(例如,您可以将枚举的所有有效字符串值放在HashSet中,然后检查设置为查看它是否有效,这可能是valueOf方法所做的事情)

现在,如果上述方法是“更好”或更好,那也是非常主观的。 如果您在循环中进行validation并且想要拒绝包含无效数据的任何内容,那么exception方法可能是最好的。 如果你想标记所有不合适的元素,那么任何一种方法都可行……如果存在大量有问题的数据,HashSet可能会更快,因为你不必生成很多新的exception对象,但即便如此表现几乎可以忽略不计。