使用例外来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
,所以通常的做法是在所有大写中声明它们,例如STREAMING
和PROGRESSIVE
( Java Tutorials – Enums )。
我会说这取决于。
如果输入来自combobox或其他任何内容的GUI元素,其中枚举值是唯一可供选择的 – 那么您的方法就可以了。 在这里,不同的价值实际上是一个例外。
但是如果您正在制作控制台应用程序,或者文本文件可能会输入任何内容,那么结果会有所不同,那么枚举值不应被视为exception。 您应该使用这种方法的正常if-else或case。
通常:仅在特殊情况下使用exception,而不是在真正可能发生的情况下使用exception。
没有单一的“正确”方式来validation,你所拥有的肯定会是我validation的方式,但还有其他方法(例如,您可以将枚举的所有有效字符串值放在HashSet中,然后检查设置为查看它是否有效,这可能是valueOf方法所做的事情)
现在,如果上述方法是“更好”或更好,那也是非常主观的。 如果您在循环中进行validation并且想要拒绝包含无效数据的任何内容,那么exception方法可能是最好的。 如果你想标记所有不合适的元素,那么任何一种方法都可行……如果存在大量有问题的数据,HashSet可能会更快,因为你不必生成很多新的exception对象,但即便如此表现几乎可以忽略不计。