I've recently read about this and seen people using this class, but in pretty much all cases, using null
would've worked as well - if not more intuitively. Can someone provide a concrete example where Optional
would achieve something that null
couldn't or in a much cleaner way? The only thing I can think of is to use it with Maps
that don't accept null
keys, but even that could be done with a side "mapping" of null's value. Can anyone provide me with a more convincing argument?
-
12random rant: i hate it when people overuse a "pattern" and make the code look so ugly for some theoretical benefit that doesn't exist... – RAY Oct 12 '12 at 08:46
-
As of Java8, I would not use this Guava class anymore because it's less powerful than the JDK one. See http://stackoverflow.com/a/10756992/82609 – Sebastien Lorber Apr 04 '14 at 09:15
4 Answers
Guava team member here.
Probably the single biggest disadvantage of null
is that it's not obvious what it should mean in any given context: it doesn't have an illustrative name. It's not always obvious that null
means "no value for this parameter" -- heck, as a return value, sometimes it means "error", or even "success" (!!), or simply "the correct answer is nothing". Optional
is frequently the concept you actually mean when you make a variable nullable, but not always. When it isn't, we recommend that you write your own class, similar to Optional
but with a different naming scheme, to make clear what you actually mean.
But I would say the biggest advantage of Optional
isn't in readability: the advantage is its idiot-proof-ness. It forces you to actively think about the absent case if you want your program to compile at all, since you have to actively unwrap the Optional
and address that case. Null makes it disturbingly easy to simply forget things, and though FindBugs helps, I don't think it addresses the issue nearly as well. This is especially relevant when you're returning values that may or may not be "present." You (and others) are far more likely to forget that other.method(a, b)
could return a null
value than you're likely to forget that a
could be null
when you're implementing other.method
. Returning Optional
makes it impossible for callers to forget that case, since they have to unwrap the object themselves.
For these reasons, we recommend that you use Optional
as a return type for your methods, but not necessarily in your method arguments.
(This is totally cribbed, by the way, from the discussion here.)

- 14,004
- 9
- 70
- 110

- 191,574
- 25
- 345
- 413
-
3+1 for a great explanation. I don't know if this is the inspiration, but I would add a pointer to option types in SML, OCaml, and F#, which have many of the same semantics. – Adam Mihalcin Mar 05 '12 at 03:45
-
2Always great to get answer from someone who was directly involved. I'd have +1'd just for that. Would +1 more for a great answer. (but I can't.) I think the point about having it as a return value to force consumers of a unfamiliar method to make an effort to acknowledge that a "nothing" can be returned is one compelling reason. I don't like though how it is being overused (or even abused). e.g, I feel really uneasy when seeing people put Optionals as values into Maps. Map returing null for a non-existent/unmapped key is a well established paradigm... No need to make it more complicated... – RAY Mar 05 '12 at 05:38
-
9It's well-established that `Map` returns `null` if a key is unmapped, but recall that if you do `map.put(key, null)`, then `map.containsKey(key)` will return `true` but `map.get(key)` will return `null`. `Optional` can be handy in clearing up the distinction between the "explicitly mapped to null" case and the "not present in the map" case. I'll grant that `Optional` can be abused, but I'm not yet convinced that the case you describe is an abuse. – Louis Wasserman Mar 05 '12 at 06:21
-
8To use an antiquated analogy, there used to be these giant things called "phone books" :-) and if I asked you to look up someone's number and you said "there's no number for that person" I'd say "what do you mean, they're in there with an unlisted number or you just couldn't find an entry for them at all?" Those two possible responses map nicely to Optional.absent() and null respectively. Optional.absent() is the definitive "positive negative." – Kevin Bourrillion Mar 06 '12 at 01:37
-
1Yeah, but that requires you to do a map lookup twice, which can be unpleasantly expensive, especially e.g. for a `TreeMap` in which each lookup costs `O(log n)`. For some of us -- myself included -- that inefficiency grates. – Louis Wasserman Mar 06 '12 at 04:09
-
1That's fair. Perhaps it's just my personal preference, but I don't like the wrapping and unwrapping. Makes the code just that tiny bit uglier. When possible (e.g. when the value type is as general as, say, Object, or an interface), I'd usually create an object that represents that "found, but not valid" value. – RAY Mar 06 '12 at 09:00
-
1That's a totally legit approach, too! It just doesn't work in all cases, and it only works when the value type satisfies certain conditions. – Louis Wasserman Mar 06 '12 at 09:17
-
3@RAY: In a way, `Optional
` **is** that "found, but not valid" value. Or more precisely, `Optional – Daniel Pryden Mar 07 '12 at 00:03` is a way to [decorate](http://en.wikipedia.org/wiki/Decorator_pattern) any type `T` with an extra "found, but not valid" value -- creating a new type by combining two existing types. If you have a hundred classes, it can get messy to have to create a separate "found, but not valid" value for each one, but `Optional ` can easily work for all of them. -
Yeah, agreed. I can see that. But as I said, it's probably just my personal preference that I need that extra layer of wrapping and unwrapping, when another object is available. – RAY Mar 07 '12 at 09:47
-
Great discussion here. Thanks, everyone. @RAY, I agree with you that it can be a little bit ugly to have Optional floating around, and that `map.containsKey` is a reasonable way to check for presence, and that the `Optional` pattern can be overused (sometimes it's nice to have code that is less type-safe but more readable, which is why some people tend to prefer dynamic languages). That being said, I've seen `null` checks at places that drive me nuts, where `@Nonnull` or `Optional` would have simplified things -- but the programmers had no way of knowing if the collection could house a null – Jake Toronto Nov 25 '14 at 16:00
-
I don't know. I never used Optional, and I don't return meaningless null values. When something don't works well I throw exceptions. I can have exceptions for all the multiple situations and error flows avoiding returning meaningless null values. I'm not sure if Optional is to solve this problem... – John John Pichler Feb 11 '15 at 01:05
-
Here goes +100 :) Is there any object creation (optional object) overhead in java ee applications? – pinkpanther Apr 23 '15 at 14:03
-
It really looks like the Maybe
Monad pattern from Haskell.
You should read the following, Wikipedia Monad (functional programming):
And read From Optional to Monad with Guava on Kerflyn's Blog, which discusses about the Optional of Guava used as a Monad:
Edit:
With Java8, there's a built-in Optional that has monadic operators like flatMap
. This has been a controversial subject but finally has been implemented.
See http://www.nurkiewicz.com/2013/08/optional-in-java-8-cheat-sheet.html
public Optional<String> tryFindSimilar(String s) //...
Optional<Optional<String>> bad = opt.map(this::tryFindSimilar);
Optional<String> similar = opt.flatMap(this::tryFindSimilar);
The flatMap
operator is essential to allow monadic operations, and permits to easily chain calls that all return Optional results.
Think about it, if you used the map
operator 5 times you would end up with an Optional<Optional<Optional<Optional<Optional<String>>>>>
, while using flatMap
would give you Optional<String>
Since Java8 I would rather not use Guava's Optional which is less powerful.

- 47,227
- 18
- 148
- 244

- 89,644
- 67
- 288
- 419
One good reason to use it is that it makes your nulls very meaningful. Instead of returning a null that could mean many things (like error, or failure, or empty,etc) you can put a 'name' to your null. Look at this example:
lets define a basic POJO:
class PersonDetails {
String person;
String comments;
public PersonDetails(String person, String comments) {
this.person = person;
this.comments = comments;
}
public String getPerson() {
return person;
}
public String getComments() {
return comments;
}
}
Now lets make use of this simple POJO:
public Optional<PersonDetails> getPersonDetailstWithOptional () {
PersonDetails details = null; /*details of the person are empty but to the caller this is meaningless,
lets make the return value more meaningful*/
if (details == null) {
//return an absent here, caller can check for absent to signify details are not present
return Optional.absent();
} else {
//else return the details wrapped in a guava 'optional'
return Optional.of(details);
}
}
Now lets avoid using null and do our checks with Optional so its meaningful
public void checkUsingOptional () {
Optional<PersonDetails> details = getPersonDetailstWithOptional();
/*below condition checks if persons details are present (notice we dont check if person details are null,
we use something more meaningful. Guava optional forces this with the implementation)*/
if (details.isPresent()) {
PersonDetails details = details.get();
// proceed with further processing
logger.info(details);
} else {
// do nothing
logger.info("object was null");
}
assertFalse(details.isPresent());
}
thus in the end its a way to make nulls meaningful, & less ambiguity.

- 60,549
- 65
- 286
- 456
The most important advantage of Optional is that it adds more details to the contract between the implementer and caller of a function. For this reason is both useful for parameters and return type.
If you make the convention to always have Optional
for possible null objects you add more clarifications to cases like:
Optional<Integer> maxPrime(Optional<Integer> from, Optional<Integer> to)
The contract here clearly specifies that there is a chance that a result is not returned but also shows that it will work with
from
andto
as absent.Optional<Integer> maxPrime(Optional<Integer> from, Integer to)
The contract specifies that the from is optional so an absent value might have a special meaning like start from 2. I can expect that a null value for the
to
parameter will throw an exception.
So the good part of using Optional is that the contract became both descriptive (similar with @NotNull
annotation) but also formal since you must write code .get()
to cope with Optional
.

- 1
- 1

- 8,777
- 5
- 67
- 76
-
-
I chose the wrong example on the return. With collections you can make the convention to always return an empty collection instead a null value. If this convention is used you don't need optional for collections. Optional could be perceived as a collection with zero or one element so it is not needed to put it around other collection. – raisercostin Jun 14 '13 at 17:19
-
2depending on the context, there could be a meaningful difference between a list with 0 items and an absent list. – plasma147 Oct 21 '14 at 10:22