I've read here why Optional.of()
should be used over Optional.ofNullable()
, but the answer didn't satisfy me at all, so I ask slightly different:
If you are SURE that your method does not return null
, why should you use Optional
at all? As far as I know, the more or less only purpose of it is to remind the "user of a method", that he might have to deal with null
-values. If he does not have to deal with null
-values, why should he be bothered with an Optional
?
I ask, because I recently made my service-layer return Optionals instead of nulls (in certain situations). I used Optional.of()
and was highly confused when it threw a NullPointer.
A sample of what I did:
Optional valueFromDB = getUserById("12");
User user = valueFromDB.get();
.....
public Optional<User> getUserById(String id) {
//...
return Optional.of(userRepository.findOne(id)); // NullPointerException!
}
If null is not possible, I don't see why one would wrap it in an Optional
. The dude in the linked answer said "well, if a NullPointer happens, it happens right away!" But do I really want that? If the sole purpose of an Optional
is, to remind the programmer who gets such an object, to keep null
in mind (he HAS to unwrap it), why should I want to have NullPointerException
at wrapping-time?
Edit: I needed to edit the question, because it got marked as duplicate, even though I already linked said question from the start. I also did explain, why the answer did not satisfy me, but now I need to edit my text with an explanation. But here is some appendix to what I want to ask, since I got 5 answers and everyone answers a different case, but none fully covered what I try to ask here:
Is there a reason, that Optional.of(null) is impossible and they specifically added Optional.ofNullable() for the null case?
Using streams should not be the problem with my idea of the implementation.
I got a lot of insight from your answers, thanks for that. But the real question has not been answered until now, as far as I can tell/read/understand.
Maybe I should have asked: "What if we remove the Optional.of()
method and only allow Optional.ofNullable()
in Java 9, would there be any problem except backwards-compatibility?"
The other reason to use Optional.of (value) when you know that value can't be null is that if you want to do additional filtering operations on that Optional.
This is another usage against Optional intention. Optional wraps objects with another level of abstraction, which, in that case, simply adds extra boilerplate code. ... ... As you can see, now the getter returns an Optional. Don't take this example as a rule for transforming all your getters like this.
However, using Optional in Domain Model entities is possible, as shown in the following example. ... ... ... ... Don't force call sites to create Optionals. Do not use Optional as fields or in setters and constructors' arguments. Using Optional in methods arguments is another common mistake.
Or you have conditional logic which creates an optional in several branches and in single branch you are sure that it's non-null. Because Optional means that it can be present, or absent. Absent != null. null in this case means "I expect foobar to be present, but due to a bug it is null".
You are mixing up the API design rationale with knowledge within a particular implementation code. It’s perfectly possible that a method declares to return an Optional
, because the value might be absent, while at a certain code location within the method, it is known to be definitely present. I.e.
String content;
public Optional<String> firstMatch(String pattern) {
Matcher m = Pattern.compile(pattern).matcher(content);
return m.find()? Optional.of(m.group()): Optional.empty();
}
This method’s return type denotes a String
that might be absent, while at the code locations creating an Optional
instance, it is known whether the value is present or absent. It’s not about detecting a null
value here.
Likewise, within the Stream API methods findFirst()
and findAny()
, it will be known at one point, whether there is a matching element, whereas supporting the conversion of its presence to absence in case of a matching null
element is explicitly unsupported and supposed to raise a NullPointerException
, per specification. Therefore, Optional.of
will be used to return the matching element, which you can easily recognize in the stack trace when using Stream.of((Object)null) .findAny();
The other reason to use Optional.of(value)
when you know that value
can't be null is that if you want to do additional filtering operations on that Optional
.
For example:
public static long getPageSizeFrom(HttpServletRequest request) {
return Optional.of(request.getParameter("pageSize"))
.filter(StringUtils::isNumeric)
.map(Long::valueOf)
.filter(page::hasPageSize)
.orElse(page::getDefaultPageSize)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With