我正在尝试检查用户传递的值是否有效。这是我写的代码。
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
,这是显而易见的。
但我的问题是:这是验证的正确方法吗?因为我们正在使用Java的异常机制来验证。
有人可以建议一个更好的主意,或者我上面编码的内容是最好的选择吗?
----- EDIT --------
我想讨论的另一个案例:
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");
}
}
这是一个好主意吗?或者应该有我们自己的解析机制?
答案 0 :(得分:9)
例外情况应该用于例外情况;你不希望发生的事情。验证输入不是很特别。
Josh Bloch实际上在他的“Effective Java”一书中特别概述了这一点,IMHO是每个Java程序员应该拥有的东西。
编辑:这实际上是解决问题的一个非常好的答案:
答案 1 :(得分:2)
通常最好不要捕获或丢弃未经检查的表达式(IllegalArgumentException
是RuntimeException
,其计为“未选中”)。有关详细信息,请参阅the Java Tutorials - Exceptions。如果可以避免它,请尝试重写代码,以便不需要捕获运行时异常。这是一个有争议的问题,但运行时异常存在的原因是:它们帮助程序员识别错误。如果你抓住了它们,那么这个bug就没有被修复,它只是被避免了。尝试使用if-else语句?
根据the API,“名称必须与用于声明枚举常量的标识符完全匹配。”我相信这意味着参数区分大小写。此外,valueOf
方法的返回类型是某种类型,而不是void
,因此您不能在try
块中包含该语句。 try
块应包含命令或void
方法,例如int x = 3;
或System.out.println(3);
或其他。
-------- EDIT -------
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
语句,测试给定字符串的相等性。
-Chris
PS:关于命名约定,因为枚举常量是隐式static final
,所以通常的做法是在所有大写中声明它们,例如STREAMING
和PROGRESSIVE
(the Java Tutorials - Enums )。
答案 2 :(得分:1)
我说这取决于。
如果输入来自组合框或其他任何内容的GUI元素,其中枚举值是唯一可供选择的 - 那么您的方法就可以了。在这里,不同的价值确实是一个例外。
但是如果您正在制作控制台应用程序,或者文本文件可能会输入任何内容,那么结果会有所不同,那么枚举值不应被视为异常。你应该使用这种方法的正常if-else或case。
通常:仅针对特殊情况使用例外,而不是针对真正可能发生的事情使用例外。
答案 3 :(得分:1)
没有单一的“正确”方式来验证,你所拥有的肯定会是我验证的方式,但还有其他方法(例如你可以将枚举的所有有效字符串值放在HashSet中然后检查该集合以查看它是否有效,这可能是valueOf方法所做的事情)
现在,如果上述方法是“更好”或更好,那也是非常主观的。如果您在循环中进行验证并且想要拒绝包含无效数据的任何内容,那么异常方法可能是最好的。如果你想标记所有不合适的元素,那么任何一种方法都可行....如果存在大量有问题的数据,HashSet可能会更快,因为你不必生成很多新的异常对象,但即便如此表现几乎可以忽略不计。