使用try/catch时如何返回声明的方法类型?

9nvpjoqh  于 2021-08-20  发布在  Java
关注(0)|答案(3)|浏览(312)

在一个 switch 语句在一些情况下,我需要将字符串形式的用户输入解析为日期对象。我正在使用 java.text.SimpleDateFormat ,而不是示例化和调用 parse 对于每种情况,我都希望将日期解析封装在某种实用方法中。重要的是,当用户输入的字符串与传递给 SimpleDateFormat .
我在java中经常遇到的问题是将 return 陈述这就是我尝试过的:

public class MainMenu {

    // a bunch of other stuff

    public static Date parseStrDate(String dateStr) throws ParseException {
        String pattern = "yyyy/mm/dd";
        SimpleDateFormat dateParser = new SimpleDateFormat(pattern);
        try {
            Date date = dateParser.parse(dateStr); 
        }
        catch (ParseException e) {
            System.out.println(e);
        }
        return date; 
    }
}

通过这种方式实现,编译器抱怨 date 未定义,因为它仅在try子上下文中定义。如果我想从火车站回来 try 上下文并删除最后一个 return date; ,编译程序抱怨它期望 return 方法声明中承诺的语句。我也试过先定义 date 在下面方法的范围内 pattern 希望它只在 try 陈述不过,我也不去那里。开始觉得整个实用程序方法可能不是要走的路线。对如何实施有何意见?

lhcgjxsq

lhcgjxsq1#

这在很大程度上取决于您返回的类型以及 Exception 就您的方法流而言是指。
例如,在以下情况下,发送结果通知失败,但仍可以返回结果:

private final Notifier notifier;

public String getResult() {
    final String result = "meow";

    try {
        this.notifier.notifyOf(result);
    } catch (final IOException ioEx) {
        System.out.println("Couldn't notify");
    }

    return result;
}

在其他情况下,您可以返回一些关于发生了什么的信息。例如,假设您的返回类型是 Response 对象,该对象具有 isError 标记,然后您可以执行以下操作:

public Response getResponse(final Request request) {
    try {
        return this.process(request);
    } catch (final Exception ex) {
        return Response.forError().withMessage("Couldn't process");
    }
}

对于您发布的方法,我认为对于不可解析的 String (在大多数上下文中没有默认的“日期”)。因此,对我来说,处理方式类似于:

public Date parseDateStr(final String input) {
    try {
        return this.dateParser.parse(input);
    } catch (final ParseException pEx) {
        throw new IllegalArgumentException("Couldn't parse date-string: " + input);
    }
}

其他时候,只是传播 Exception 返回到任何被调用的方法都是合适的。这实际上取决于上下文,以及在特定情况下,您是否可以返回或执行一些合理的操作 Exception .
正如另一个答案所提到的,您可以通过在 try 布洛克:但这不一定是最好的做法,除非你能给出合理的“违约”。

uinbv5nw

uinbv5nw2#

正如beundead的回答所说,没有合理的违约,因此抛出异常是一个不错的选择。我认为最好抛出一个checked异常来强制调用方处理丢失的日期。不能返回日期这一事实是函数api的一部分,应该公开。
还有一个合理的选择,就是将返回类型更改为 Optional<Date> .

public static Optional<Date> parseStrDate (String dateStr) {
        String pattern = "yyyy/mm/dd";
        SimpleDateFormat dateParser = new SimpleDateFormat(pattern);
        try {
            return Optional.of(dateParser.parse (dateStr));
        } catch (ParseException e) {
            // it may be useful to log the exception here, if bad dates indicate a wider problem.
            return Optional.empty();
        }
    }

这将强制调用方处理丢失日期的情况。
最佳解决方案取决于预期的是无效日期(例如,字符串来自用户输入)还是真正的异常日期(例如,字符串来自另一个服务,只有在某个地方引入错误时才无效)。
我也会提出动议 patternstatic final 封闭类的成员。正如内森·休斯所指出的, SimpleDateFormat 不是线程安全的,所以我们需要为每个方法调用创建一个示例。
最好使用新的日期api:

package org.example;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Optional;

public class DateExample {
    // this class is thread safe
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd");

    public static Optional<LocalDate> parseStrDate (String dateStr) {
        try {
            return Optional.of(LocalDate.parse(dateStr, DATE_TIME_FORMATTER));
        } catch (DateTimeParseException e) {
            // it may be useful to log the exception here, if bad dates indicate a wider problem.
            return Optional.empty();
        }
    }
}

还有一个基本测试:

package org.example;

import org.junit.jupiter.api.Test;
import java.time.LocalDate;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class TestDateExample {
    @Test
    public void testValidDate() {
        assertEquals(LocalDate.of(2021, 7, 4), DateExample.parseStrDate("2021/07/04").get());
    }

    @Test
    public void testInvalidDate() {
        assertEquals(Optional.empty(), DateExample.parseStrDate("2021/13/04"));
    }
}
t40tm48m

t40tm48m3#

class MainMenu {
    // a bunch of other stuff

    public static Date parseStrDate (String dateStr) {
        String pattern = "yyyy/mm/dd";
        SimpleDateFormat dateParser = new SimpleDateFormat (pattern);
        Date date = new Date (0L);
        try {
            date = dateParser.parse (dateStr);
        } catch (ParseException e) {
            System.out.println (e);
        }
        return date;
    }
}

定义 datetry . 用一个无意义的日期初始化它,或者 null . 像以前一样解析。
移除 throws 因为它不是 throw 因为它 catch 锿。

相关问题