如果我知道不会抛出异常,则抑制 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.parse
有 throws 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);
}
是否可以抑制 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.parse
有 throws 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);
}