I want to throw a custom exception in case parsing fails, but the compiler complains that there is an unhandled ParserException
that comes from the parse()
method.
But What am I missing?
My code:
public void validateConstraints(RequestType body) {
SimpleDateFormat simpleDateFormatYearMonth = new SimpleDateFormat("yyyy-MM-dd");
Date date = Optional
.ofNullable(body.date())
.map(simpleDateFormatYearMonth::parse)
.orElseThrow(() -> new InvalidCustomException(""));
}
CodePudding user response:
TL;DR
- Your apparent issue stems from the fact
java.util.Function
as well as many other functional interfaces doesn't declare to throw any checked Exceptions in its abstract method. For that reason, implementations can't violate the contract providing behavior which is less safe than declared.
Here's a quote from the Java Language Specification §8.4.8.3.
Requirements in Overriding and Hiding:
For every checked exception type listed in the
throws
clause ofm2
, that same exception class or one of its supertypes must occur in the erasure (§4.6) of thethrows
clause ofm1
; otherwise, a compile-time error occurs.
With that being said, you can't propagate a checked exception outside the lambda or method reference (since it's not declared, it should be handled right on the spot).
Creating an
Optional
only for the purpose of hiding null-check, and chaining methods on it is a misuse ofOptional
since it goes against its design goal.java.util.Date
(andjava.sql.Date
) as well asSimpleDateFormat
are obsolete since Java 8 (reminder: this version was released more than 10 years ago). As a replacement we have a new Time API, represented by classes that reside injava.time
package, likeInstant
,LocalDateTime
,DateTimeFormatter
, etc.
Avoid using Optional to replace Null-checks
The design goal of the Optional
is to serve as a return type, and its method ofNullable()
is supposed to wrap a nullable return value, not to perform validation.
You might be interested in reading:
Here's a short quote from the linked above answer by @StuartMarks, Java and OpenJDK developer:
A typical code smell is, instead of the code using method chaining to handle an Optional returned from some method, it creates an Optional from something that's nullable, in order to chain methods and avoid conditionals.
To validate if a value is not null
JDK offers overloaded method Objects.requireNoneNull()
, which was specifically designed for that purpose. But in this case it's not applicable because you need to throw your custom exception (requireNoneNull()
operates via NPE, you can only provide a custom message).
The last thing worth to point out before diving into the solution, is that there's nothing wrong with implicit null-checks (if you have quite a bit of them that's an issue, which is rooted in a way your classes and behavior are designed, rather than related to the tools offered by the language).
Therefore, I would advise to implement this functionality using a plain conditional logic:
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;
}