Chr*_*ore 37 java parsing numbers
看到Java没有可空类型,也没有TryParse(),如何在不抛出异常的情况下处理输入验证?
通常的方式:
String userdata = /*value from gui*/
int val;
try
{
val = Integer.parseInt(userdata);
}
catch (NumberFormatException nfe)
{
// bad data - set to sentinel
val = Integer.MIN_VALUE;
}
Run Code Online (Sandbox Code Playgroud)
我可以使用正则表达式来检查它是否可解析,但这似乎也是很多开销.
处理这种情况的最佳做法是什么?
编辑:理由:关于异常处理,有很多关于SO的讨论,一般的态度是异常应仅用于意外情况.但是,我认为糟糕的用户输入是预期的,并不罕见.是的,这确实是一个学术观点.
进一步编辑:
一些答案证明了SO究竟出了什么问题.你忽略了被问到的问题,并回答了与之无关的另一个问题.问题不是要求层之间的过渡.如果数字是不可解析的,那么问题不在于询问返回什么.如你所知,val = Integer.MIN_VALUE; 对于完全无上下文的代码片段来自应用程序的应用程序来说,它是完全正确的选项.
Ste*_*ler 28
我问是否有开源实用程序库有方法为您解析,答案是肯定的!
从Apache Commons Lang您可以使用NumberUtils.toInt:
// returns defaultValue if the string cannot be parsed.
int i = org.apache.commons.lang.math.NumberUtils.toInt(s, defaultValue);
Run Code Online (Sandbox Code Playgroud)
从Google Guava您可以使用Ints.tryParse:
// returns null if the string cannot be parsed
// Will throw a NullPointerException if the string is null
Integer i = com.google.common.primitives.Ints.tryParse(s);
Run Code Online (Sandbox Code Playgroud)
没有必要编写自己的方法来解析数字而不抛出异常.
Tom*_*ine 17
对于用户提供的数据,Integer.parseInt通常是错误的方法,因为它不支持国际化.该java.text包是你的(详细)的朋友.
try {
NumberFormat format = NumberFormat.getIntegerInstance(locale);
format.setParseIntegerOnly(true);
format.setMaximumIntegerDigits(9);
ParsePosition pos = new ParsePosition(0);
int val = format.parse(str, pos).intValue();
if (pos.getIndex() != str.length()) {
// ... handle case of extraneous characters after digits ...
}
// ... use val ...
} catch (java.text.ParseFormatException exc) {
// ... handle this case appropriately ...
}
Run Code Online (Sandbox Code Playgroud)
Ste*_* B. 16
这几乎就是它,虽然返回MIN_VALUE有点值得怀疑,除非你确定使用你真正用作错误代码的东西是正确的.但至少我会记录错误代码行为.
可能也很有用(取决于应用程序)记录错误的输入,以便您可以跟踪.
ast*_*ite 11
你的方法有什么问题?我不认为这样做会损害你的应用程序的性能.这是正确的方法.不要过早优化.
我确定这是一个糟糕的形式,但我在Utilities类上有一组静态方法,Utilities.tryParseInt(String value)如果String是不可解析的,Utilities.tryParseInt(String value, int defaultValue)它会返回0,并允许你指定一个值,如果parseInt()抛出异常.
我相信有时候输入错误输入的已知值是完全可以接受的.一个非常人为的例子:你要求用户提供YYYYMMDD格式的日期,他们会给你不好的输入.根据程序要求做某事Utilities.tryParseInt(date, 19000101)或完全可以接受Utilities.tryParseInt(date, 29991231);.