我想在解析失败的情况下抛出一个自定义异常,但是编译器抱怨有一个来自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.
重写和隐藏中的要求:
对于
m2
的throws
子句中列出的每个检查异常类型,该异常类或其超类型之一必须出现在m1
的throws
子句的擦除(§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操作,您只能提供自定义消息)。
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;
}