如果我知道不会抛出异常,则抑制 Java 豁免

Supress Java exeption if I know an exeption won't be thrown

是否可以抑制 Java 代码中的异常?假设我正在尝试做一些像这样基本的事情:

Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2021-01-01")

如果字符串格式不正确,.parse() 方法会抛出异常,因此需要一个 try-catch 块:

try {
    Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2021-01-01")
} catch (ParseExeption e) {
    //Nothing to do here
}

但是,我知道不会抛出异常的事实。有没有办法避免使用 try-catch 块?

不幸的是,没有。您无法隐藏此异常。

由于 DateFormat.parsethrows ParseException,您需要在代码中捕获或为方法添加 throws ParseException 状态。

唯一不需要捕获或添加 throws 语句以使程序编译的异常是继承 RuntimeException.

的异常

在你的情况下 ParseException 不继承 RuntimeException,所以你需要抓住它或使用 throws 关键字。

偷偷摸摸的投掷方法

实际上,您可以欺骗 Java 编译器并偷偷抛出已检查的异常。

这个可以通过下一个方法实现

public static <E extends Throwable> void sneakyThrow(Throwable e) throws E {
    throw (E) e;
}

然后你可以用这个方法包装异常

try {
    Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2021-01-01")
} catch (ParseExeption e) {
    sneakyThrow(e);
}

如您所见,它 需要 try/catch 块,但您可以使用 lombok 库,它会为您完成所有工作注释 @SneakyThrows.

@SneakyThrows
public void myMethod() {
    Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2021-01-01");
}

上面的代码可以编译,但是需要使用外部库。

如果您想为 2021 年 1 月 1 日硬编码 Date,请在不使用 SimpleDateFormat 的情况下执行此操作,这样您就不必处理异常。

Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(2021, Calendar.JANUARY, 1);
Date date = cal.getTime();

在Java8+中,使用新的Java时间API:

Date date = Date.from(LocalDate.of(2021, 1, 1)
                               .atStartOfDay(ZoneId.systemDefault())
                               .toInstant());
Date date = Date.from(LocalDate.parse("2021-01-01")
                               .atStartOfDay(ZoneId.systemDefault())
                               .toInstant());
Date date = Date.from(Year.of(2021).atDay(1)
                          .atStartOfDay(ZoneId.systemDefault())
                          .toInstant());
Date date = Date.from(ZonedDateTime.of(2021, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault())
                                   .toInstant());

如果您坚持使用SimpleDateFormat,请断言它不会发生。

Date date;
try {
    date = new SimpleDateFormat("yyyy-MM-dd").parse("2021-01-01");
} catch (ParseException e) {
    throw new AssertionError("Cannot happen: " + e, e);
}