Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a real reason to use Optional.of()?

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?"

like image 219
codepleb Avatar asked Dec 16 '16 09:12

codepleb


People also ask

When to use optional of a value?

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.

What is the use of optional in JavaScript?

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.

Is it possible to use optionals in domain models?

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.

Why do optional statements have to be non-null?

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".


2 Answers

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();

like image 179
Holger Avatar answered Sep 23 '22 03:09

Holger


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)
}
like image 34
marknorkin Avatar answered Sep 24 '22 03:09

marknorkin