处理NumberFormatExeption的最佳实践

时间:2016-12-29 01:16:07

标签: java

我想知道处理NumberFormatException的最佳方式是什么?

只要用户传递空字符串,我的代码就会抛出NumberFormatException。有多种方法可以解决这个问题,但我不确定最佳方法是什么?

以下是我的代码:

if(result != null) {
    String [] values = result.trim().split(",");
    // This is where the NumberFormatException occurs
    long docId = Long.parseLong(values[0]);
    //There is more to the code but the rest is unnecessary :)  
    break;
}

我是否应该通过在解析之前检查values[0]是否为空来一起避免NumberFormatException?所以像这样:

if(result!= null) {
    String [] values = result.trim().split(",");        
    if("".equals(values[0]) {
        // This method returns void hence the empty return statement.
        return;
    } 
    long docId = Long.parseLong(values[0]);
    break;
}

或者,如果发生异常,我应该抓住它吗?

if(result!= null) {
    String [] values = result.trim().split(",");        
    try{            
        long docId = Long.parseLong(values[0]);
    } catch (NumberFormatExeption e) {
        LOGGER.warn("Exception in ThisClass :: ", e);
        return;
    }
    break;
}

或者你推荐另一种方法吗?

4 个答案:

答案 0 :(得分:3)

最简单的方法是捕捉NumberFormatException

你的选择有几个问题:

  1. 您可能会得到一个既不是数字也不是空字符串的东西。也可能得到一个对int来说太大的整数。如果发生这种情况,那么您的修复工作无效。

  2. 在switch语句中间的return可能会使您的代码更难理解。根据上下文,此可能出现问题。

  3. 如果您决定沿着避免NumberFormatException的所有可能情况的路径前进,那么您需要检查所有可能的可解析整数。这可以使用正则表达式...模数来检查正则表达式中int(或long)过大的整数是非常混乱的。

    在这种情况下,我的建议是让异常发生,并捕获/处理它们。除非......

    • 如果空字符串是常见的情况,那么将它们作为一种特殊情况处理会更有效。同样适用于其他不可解析的输入。效率是否足够重要以保证额外的复杂性取决于上下文。

    • 如果其他"坏号码"案例完全是未预料到的,可能适合 NOT 处理NumberFormatException,允许异常中止请求/崩溃应用程序,然后处理跟踪坏数据的来源维护问题。 (这也取决于具体情况......显然。)

      

    处理NumberFormatExeption的最佳做法

    在这种情况下,"最佳实践"是矛盾的。

答案 1 :(得分:1)

可以出于各种原因抛出NFE,而不仅仅是提供空字符串的用户。第二种方法处理这些。第一种方法仍然可以抛出NFE!

此外,恕我直言,这是用户提供的数据的简单数据验证。 因此,您可能希望向用户提供正确的错误消息。 (WARN日志可能不够)

在这种情况下,异常可能是处理它的一种合适的方法,即将NFE包装成更好的东西,如ValidationException of sort。 (你可能会在路上进行其他有效性检查:解析长期在某个范围内等。)

我并不认为有必要在解析long之前尝试使用正则表达式来避免获取NFE。不值得努力。

答案 2 :(得分:1)

如果您的应用程序偶尔解析数字,您应该创建一个类来标准化解析 - 并且可能还有默认行为。

解析无效数据有两种常用方法:

  1. 快速失败 - 允许抛出异常&传播,带有有意义的诊断信息。业务逻辑将被终止。
  2. Tolerant - 在提供错误输入时使用默认值,最好记录警告。业务逻辑将以默认值运行。 (你的问题暗示你倾向于采用这种方法。)
  3. 缺少数据(null / empty / blank string)可以用以下三种方式之一来处理:

    1. 空表示缺少值(不常见,结果为null),
    2. 空表示默认值,(最常见)
    3. 空是一个错误。
    4. 长话短说,最常见的方法是提供parseInt (String s, int defaultVal) 容忍的功能,并回答空白和空白。错误作为默认值。

      public static int parseInt (String s, int defaultVal) {
          if (StringUtils.isBlank(s))
              return defaultVal;
      
          try {
              return Integer.parseInt(s);
          } catch (NumberFormatException x) {
              log.warn("unparseable integer value: "+s+", using default", x);
              return defaultVal;
          }
      }
      

      这可以放在解析实用程序类或其他合适的位置。

      最后一个注意事项:解析过去常用于配置和配置。输入数据,但依赖注入框架(如Spring和CDI)现在可以为您执行大多数配置解析。但是,解析仍然与输入数据相关。

答案 3 :(得分:0)

第一种方法无法处理各种情况,因此我更倾向于使用第二种方法。