java 使用异常来验证输入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7304067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Exceptions to validate inputs
提问by Chatting_Enabled
I am trying to check whether the value passed by an user is valid constant or not. Here is the code I have written.
我正在尝试检查用户传递的值是否为有效常量。这是我写的代码。
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);
}
}
}
Now, in above code if the String passed is not withing the listed enum then it throws IllegalArgumentException
which is obvious.
现在,在上面的代码中,如果传递的字符串不属于列出的枚举,那么它会抛出IllegalArgumentException
,这是显而易见的。
But my question is: Is this the proper way to validate? As we are using Java's exception mechanism to validate.
但我的问题是:这是验证的正确方法吗?因为我们正在使用 Java 的异常机制来验证。
Can someone suggest a better idea or what I have coded above itself is the best option ?
有人可以提出更好的主意,或者我上面编码的内容本身是最好的选择?
-----EDIT--------
- - -编辑 - - - -
Another case which I wanted to discuss:
我想讨论的另一个案例:
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");
}
}
So is this a good idea ? Or there should be our own parsing mechanism?
这是个好主意吗?还是应该有我们自己的解析机制?
回答by Brian Roach
Exceptions should be used for exceptional conditions; things you don't expect to happen. Validating input isn't very exceptional.
例外应该用于例外情况;你不希望发生的事情。验证输入并不是很特别。
Josh Bloch actually outlines this specifically in his book 'Effective Java' which IMHO is something every Java programmer should have.
Josh Bloch 实际上在他的“Effective Java”一书中具体概述了这一点,恕我直言,这是每个 Java 程序员都应该拥有的东西。
EDIT:And this is actually a very good answer to how to approach the problem:
编辑:这实际上是如何解决问题的一个很好的答案:
回答by chharvey
It is usually best practice not to catch or throw unchecked expressions (IllegalArgumentException
is a RuntimeException
which counts as "unchecked"). See the Java Tutorials - Exceptionsfor more details. If you can avoid it, try rewriting your code such that a runtime exception is not needed to be caught. This is a controversial issue, but runtime exceptions exist for a reason: they help the programmer identify bugs. If you catch them, then the bug is not being fixed, it is just being avoided. Try using an if-else statement?
通常最好的做法是不要捕捉或抛出未经检查的表达式(IllegalArgumentException
是一个RuntimeException
算作“未经检查”的)。有关更多详细信息,请参阅Java 教程 - 异常。如果可以避免它,请尝试重写代码,以便不需要捕获运行时异常。这是一个有争议的问题,但运行时异常的存在是有原因的:它们帮助程序员识别错误。如果你抓住了它们,那么错误并没有被修复,它只是被避免了。尝试使用 if-else 语句?
According to the API, "the name must match exactly an identifier used to declare an enum constant." I believe this means the parameter is case-sensitive. In addition, the return type of the valueOf
method is some type, not void
, so you can't have that statement in the try
block. try
blocks should contain commands or void
methods, such as int x = 3;
or System.out.println(3);
or something.
根据API,“名称必须与用于声明枚举常量的标识符完全匹配。” 我相信这意味着该参数区分大小写。此外,该valueOf
方法的返回类型是某种类型,而不是void
,因此您不能在try
块中包含该语句。try
块应该包含命令或void
方法,例如int x = 3;
或System.out.println(3);
或什么。
--------EDIT-------
- - - - 编辑 - - - -
OP, in response to your comment:
OP,回应您的评论:
Like others here have said, it depends on what you're trying to accomplish. I assume that since you have the line Media_Delivery.valueOf("streaming");
in the try
block, that you're attempting to see whether "streaming"
is equal to one of the enum constants? In that case, you wouldn't need an if-else statement, you could simply write
就像这里的其他人所说的那样,这取决于您要实现的目标。我假设由于您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);
Or even better, if you don't want to have multiple ||
conditions, try a switch
statement that cycles through each enum constant, testing the equality of the given string.
或者更好的是,如果您不想有多个||
条件,请尝试switch
循环遍历每个枚举常量的语句,测试给定字符串的相等性。
-Chris
-克里斯
PS: on naming convention, since enum constants are implicitly static final
, it is common practice to declare them in all caps, such as STREAMING
and PROGRESSIVE
(the Java Tutorials - Enums).
PS:在命名约定上,由于枚举常量是隐式的static final
,通常的做法是用所有大写字母声明它们,例如STREAMING
和PROGRESSIVE
(Java 教程 - 枚举)。
回答by user439407
There is no single "proper" way to validate, what you have would certainly be the way I would validate, but there are other ways(for instance you could put all the valid string values of the enumeration in a HashSet and then check against that set to see if its valid, that is probably what the valueOf method does anyway)
没有单一的“正确”验证方式,您拥有的肯定是我验证的方式,但还有其他方式(例如,您可以将枚举的所有有效字符串值放在 HashSet 中,然后进行检查设置以查看其是否有效,这可能是 valueOf 方法所做的)
Now if the above approach is any "better" or not, that too is to be pretty subjective. If you are doing the validations in a loop and want to reject anything that contains invalid data, then the exception approach is probably best. If you want to flag all the inappropriate elements then either approach works.... the HashSet will probably be faster if there is a lot of problematic data as you wont have to generate a lot of new exception objects, but even then the difference in performance will be pretty negligible.
现在,如果上述方法是否“更好”,那也是非常主观的。如果您在循环中进行验证并希望拒绝任何包含无效数据的内容,那么异常方法可能是最好的。如果你想标记所有不合适的元素,那么任何一种方法都有效......如果有很多有问题的数据,HashSet 可能会更快,因为你不必生成很多新的异常对象,但即使如此,在性能将非常微不足道。
回答by dantuch
I'd say it depends.
我会说这取决于。
If input comes from GUI element like combobox or anything, where enum values are the only ones to choose - then your approach is ok. Here different value would really be an exception.
如果输入来自诸如组合框之类的 GUI 元素或任何东西,其中枚举值是唯一可供选择的值 - 那么您的方法就可以了。这里不同的价值真的是一个例外。
But if you're making console app, or textfiled with possibility to type anything then result different then enum values shouldn't be considered as exception. You should use normal if-else or cases with this approach.
但是,如果您正在制作控制台应用程序,或者可以输入任何内容的文本文件,则结果不同,则不应将枚举值视为异常。您应该使用这种方法的正常 if-else 或 case。
generally: use exceptions only for exceptional cases, and not for something that is really likeable to happen.
通常:仅在特殊情况下使用异常,而不是真正喜欢发生的事情。