可选-使用orElseThrow()的未处理异常



我想在解析失败的情况下抛出一个自定义异常,但是编译器抱怨有一个来自parse()方法的未处理的ParserException

但是我错过了什么?

我的代码:

public void validateConstraints(RequestType body) {

SimpleDateFormat simpleDateFormatYearMonth = new SimpleDateFormat("yyyy-MM-dd");

Date date = Optional
.ofNullable(body.date())
.map(simpleDateFormatYearMonth::parse)
.orElseThrow(() -> new InvalidCustomException(""));
}

TL;DR

  • 您的明显问题源于java.util.Function以及许多其他功能接口没有声明在其抽象方法中抛出任何检查异常。因此,实现不能违反提供比声明的更不安全的行为的合约。

这是Java语言规范§8.4.8.3.重写和隐藏中的要求:

对于m2throws子句中列出的每个检查异常类型,该异常类或其超类型之一必须出现在m1throws子句的擦除(§4.6)中;否则,将出现编译时错误。

话虽如此,您不能在lambda或方法引用之外传播检查异常(因为它没有声明,所以应该在现场处理)。

  • 创建Optional只是为了隐藏null检查,并在其上链接方法是对Optional的滥用,因为它违背了它的设计目标。

  • java.util.Date(和java.sql.Date)以及SimpleDateFormat自Java 8以来就已经过时了(提醒:该版本是在10多年前发布的)。作为替代,我们有一个新的时间API,由java.time包中的类表示,如Instant,LocalDateTime,DateTimeFormatter等。

避免使用Optional来替换null检查

Optional的设计目标是作为返回类型,它的方法ofNullable()应该包装一个可空的返回值,而不是执行验证。

你可能有兴趣阅读:

  • 应该使用Optional.ofNullable()进行空检查吗?

  • Java 8中可选类型的有效使用

这是上面链接的答案的简短引用,来自Java和OpenJDK开发人员@StuartMarks:

A典型的代码气味是,代码不是使用方法链来处理从某个方法返回的可选,它创建一个可选从可空的东西,为了链方法和避免条件.

为了验证一个值是否不是null, JDK提供了重载方法Objects.requireNoneNull(),这是专门为此目的设计的。但在这种情况下,它不适用,因为您需要抛出自定义异常(requireNoneNull()通过NPE操作,您只能提供自定义消息)。

在深入研究解决方案之前,值得指出的最后一件事是没有任何错误with隐式空检查(如果你有很多,这是一个问题,它植根于你的类和行为的设计方式,而不是与语言提供的工具有关)。 因此,我建议使用简单的条件逻辑来实现此功能:
public static final SimpleDateFormat YEAR_MONTH_DAY = new SimpleDateFormat("yyyy-MM-dd");
public void validateConstraints(RequestType body) {
if (tryParse(body.date()) == null) throw new InvalidCustomException("message");
}
private Date tryParse(String str) {
Date date = null;
try {
if (str != null) date = YEAR_MONTH_DAY.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}

相关内容

最新更新