使用Exceptions验证输入

时间:2011-09-05 05:08:23

标签: java

我正在尝试检查用户传递的值是否有效。这是我写的代码。

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

            }

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

4 个答案:

答案 0 :(得分:9)

例外情况应该用于例外情况;你不希望发生的事情。验证输入不是很特别。

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

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

Check valid enum values before using enum

答案 1 :(得分:2)

通常最好不要捕获或丢弃未经检查的表达式(IllegalArgumentExceptionRuntimeException,其计为“未选中”)。有关详细信息,请参阅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,所以通常的做法是在所有大写中声明它们,例如STREAMINGPROGRESSIVEthe Java Tutorials - Enums )。

答案 2 :(得分:1)

我说这取决于。

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

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

通常:仅针对特殊情况使用例外,而不是针对真正可能发生的事情使用例外。

答案 3 :(得分:1)

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

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