避免使用嵌套的try-catch块

时间:2016-12-07 00:43:22

标签: java error-handling

我有以下Java代码:

SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH");
Date date;
try {
     date = df.parse(userString);
 } catch (ParseException e) {
     date = df.parse("07/12/2016 01:00");
     LOGGER.error("Could not parse date, reverting to default");
 }

所以,我要做的是将用户输入解析为日期,如果失败,则将其替换为默认日期。

然而,第二个df.parse()需要一个自己的尝试捕获,即使这是我知道肯定会有效的值。对于第二个parse没有工作是没有任何意义的,如果它确实没有,我没有更多的事要做,我不妨终止该计划因为世界已经结束。 :)

有没有办法避免需要第二个try-catch阻止?

6 个答案:

答案 0 :(得分:3)

你说第二次尝试没有意义。这是正确的一半。是的,你说它不会失败,但Java不知道这一点。

你可以预先解析一个默认的日期引用,store作为一个类成员,并返回它(但你仍然需要尝试捕获 - 并且它不是不可变的。)

尝试减少代码行没有错。这个问题有几个答案可以帮助你解决没有try-catch的问题,但我认为这些问题使得代码不那么清晰,而且更容易出错。有一些思想学派可以避免状态标志,避免可以为空的值,不要重新分配变量等。

在这种情况下,我会使用嵌套的try-catch,继续你的生活。它有点但很难看,但比其他方法更安全,更清晰。

所以虽然这不是你问题的答案,但我发布这是一个答案,因为我认为回答这个问题会让你的代码总体上变得更糟。 :)

这就是我编写函数以获得最佳可读性,可维护性和安全性的方法......

public Date parseDate(String userString) {
    SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH");
    try {
        return df.parse(userString);
    } catch (ParseException e) {
        LOGGER.error("Could not parse date '" + userString + "' reverting to default");
        try {
            return df.parse("07/12/2016 01:00");
        } catch (ParseException shouldntHappen) {
            throw new RuntimeException(shouldntHappen);
        }
    }
}

答案 1 :(得分:2)

您可以通过在try上检查finally标记isError来设置true块中的默认日期,从而避免嵌套ParseException,如下所示:

    SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH");
    Date date1;
    Date date2;
    boolean isError = false;
    try {
         date1 = df.parse("07/12/2016 01:00");
         date2 = df.parse(userString);
     } catch (ParseException e) {
         isError= true;
         LOGGER.error("Could not parse date, reverting to default");
     } finally {
         if(isError) {
             date2 = date1;
         }
     }

答案 2 :(得分:2)

如果您的默认日期是预先确定的,这意味着如果您不需要解析它,则可以使用

date = new Date(1468285200L * 1000); // unix time * 1000(milliseconds)

否则只需像这样使用SimpleDateFormat.parse(String text, ParsePosition pos);

date = df.parse("07/12/2016 01:00", new ParsePosition(0));

哪个不会抛出任何ParseException但会根据解析是否成功返回日期或null

答案 3 :(得分:0)

我会将此功能移动到一个方法,然后可以重复使用

public static void main (String [] args) 
{

    Date dt = setDate ("07/12/2016 x1:00");
    if (dt == null) {
        dt = setDate ("07/12/2016 01:00");
    }

    System.out.println(dt);
}

private static Date setDate(String in) {

    SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH");
    Date date = null;
    try {
         date = df.parse(in);
     } catch (ParseException e) {
         System.out.println("Could not parse date, reverting to default");
     }      

    return date;
}

答案 4 :(得分:0)

创建特定日期的正确方法是使用现有的日期时间类:

LocalDateTime local = LocalDateTime.of(2016, 7, 12, 1, 0);
ZonedDateTime zoned = ZonedDateTime.of(local, ZoneId.systemDefault());
date = Date.from(zoned.toInstant());

您也可以使用日历。如果您使用的是比Java 8更早的Java版本,那么Calendar是唯一的方法:

Calendar calendar = Calendar.getInstance();
calendar.set(2016, Calendar.JULY, 12, 1, 0, 0);
date = calendar.getTime();

警告:Calendar.JULY 等于7.使用月份常量来避免错误。

答案 5 :(得分:-1)

检查ParseException异常。所以你必须在try catch块中编写它或者在方法声明中写入抛出PraseException。但是你的调用方法必须捕获异常。 没有其他方法可以避免检查异常