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