Java 捕捉数字格式异常是一种糟糕的做法吗?
我必须解析一个可以采用十六进制值或其他非十六进制值的字符串Java 捕捉数字格式异常是一种糟糕的做法吗?,java,parsing,exception,exception-handling,numberformatexception,Java,Parsing,Exception,Exception Handling,Numberformatexception,我必须解析一个可以采用十六进制值或其他非十六进制值的字符串 0xff,0x31或A,PC,标签,等等 我使用此代码来划分两种情况: String input = readInput(); try { int hex = Integer.decode(input); // use hex ... } catch (NumberFormatException e) { // input is not a hex, continue parsing }
0xff
,0x31
或A
,PC
,标签
,等等
我使用此代码来划分两种情况:
String input = readInput();
try {
int hex = Integer.decode(input);
// use hex ...
} catch (NumberFormatException e) {
// input is not a hex, continue parsing
}
这段代码会被认为是“丑陋”的还是难以阅读的?还有其他(可能更优雅的)解决方案吗
编辑:我想澄清一下(在我的例子中)不存在错误的输入:我只需要区分它是否是十六进制数。
为了完整起见,我做了一个简单的assbler。这取决于上下文,在许多情况下,这是不好的,但是如果这是一个很可能有坏输入的地方,并且你有一个默认设置,那么你会想要抓住它。你的问题是我今天看到的关于这个问题的第二个问题 不,捕捉这个异常非常合适 捕获更显式的异常(如“NumberFormatException”)肯定比捕获一般的“异常”更好 我想 附言: 你提出的例外是:在这个层次上,或者更高层次上,是一个不同的问题 经验法则是“你知道发生了什么,以及如何最好地恢复的最低水平。” 或者,换言之(引用下面的链接): “只有当方法能够以某种合理的方式处理异常时,才应捕获异常。” 下面是一些讨论:
-
不,这不是“坏习惯”。这要视情况而定
例如,作为一个Android,如果用户将字符串“123a”输入到一个只接受整数的文本框中,并随后进行解析,则会抛出一个异常,导致应用程序崩溃。在这种情况下,捕获异常并提示用户重新输入文本是非常有意义的。它的
不是关于您的代码看起来有多好
,而是您的代码工作得有多好
。。。。。。。。。。
当然,它应该是可读的,正如一句名言所说…
任何傻瓜都能编写计算机能理解的代码,但只有伟大的程序员才能编写人类能理解的代码。
在某些情况下,这是非常好的,因为您需要有这样的例外情况
当您想要捕获属于同一继承树的多个异常时,
然后创建一个try块,并从更具体到更抽象的多个catch块。
例如:
以上捕获已从更具体到更抽象进行级联,以便捕获异常的原因。
如果没有继承,那么catch可以是任意顺序的…在您的情况下,我更喜欢类似于
isHexDigit
的方法,而不是使用NumberFormatException
,除非对数据的格式有一些假设——从您的描述来看,似乎没有关于何时会遇到十六进制数与非十六进制数的假设
这是因为应该使用异常来处理异常情况,如果数据的期望值是:十六进制数字或非十六进制数字,用空格分隔,那么遇到十六进制数字以外的令牌就没有什么异常了
此外,使用异常确实会降低代码的可读性:没有关于数据的注释,它隐藏了这样一个事实,即散布的非十六进制数字是可接受的和预期的输入
在声明了这个偏好之后,我可能会使用异常处理来处理这个案例,我当然看到了很多这样做的代码。decode/parseInt/NumberFormatException的组合为您提供了许多好的功能。如果没有明确的注释来解释我在做什么,我不会使用它。异常处理是Java编程语言不可分割的一部分(也是设计目标之一)。。。你不应该仅仅因为觉得它们“丑”就把它们扔掉
这样说,如果您想要一个简单易读的方式来处理<代码> NoMultFraseExtabor >代码> s,那么您可以考虑使用该类。p>
toInt(String str,int defaultValue)
方法将String
转换为int
,如果转换失败,则返回默认值。如果字符串为null
,则返回默认值
NumberUtils.toInt(null, 1) = 1
NumberUtils.toInt("", 1) = 1
NumberUtils.toInt("1", 0) = 1
该方法封装了异常捕获和处理,如下所示。因此,客户端只需要进行一次方法调用
public static int toInt(String str, int defaultValue) {
if(str == null) {
return defaultValue;
}
try {
return Integer.parseInt(str);
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
这是你能做的最好的了。一个方法要么返回某种成功/错误指示器,要么抛出异常,这只是一个最方便的问题。这里是Sun为我们做的决定,所以不需要争论
关于这一点,最让我感到不安的是,异常将包括一个完整的堆栈跟踪!在您的特定情况下,如果您正在读取数以百万计的这些字符串,您将注意到(完全不必要的)性能差。如果它对你很重要,你可能想考虑编写你自己的方法(你可以使用Sun代码作为指南)。然后你可以自己决定是否使用一个异常。如果您这样做了,请随身携带异常的静态副本,并始终抛出该副本以节省分配时间。并重写
fillInStackTrace
,这样它就不起任何作用,而且在异常中也不会有无意义的堆栈跟踪。这不一定是一种坏做法,但它可能有助于向我们展示输入的样子。在我看来,你永远无法做足够的错误检查。我认为这很难看,也很难阅读,但没有更好的解决办法。这就是我不喜欢你可能会发现的相关检查异常的原因之一。你解决过这个问题吗?@AlexLockwood我仍然希望得到新的答案…没有运气:)所以我会
NumberUtils.toInt(null, 1) = 1
NumberUtils.toInt("", 1) = 1
NumberUtils.toInt("1", 0) = 1
public static int toInt(String str, int defaultValue) {
if(str == null) {
return defaultValue;
}
try {
return Integer.parseInt(str);
} catch (NumberFormatException nfe) {
return defaultValue;
}
}