The main design goal of Optional is to provide a means for a function returning a value to indicate the absence of a return value. See this discussion. This allows the caller to continue a chain of fluent method calls.

This most closely matches use case #1 in the OP's question. Although, absence of a value is a more precise formulation than null since something like IntStream.findFirst could never return null.


For use case #2, passing an optional argument to a method, this could be made to work, but it's rather clumsy. Suppose you have a method that takes a string followed by an optional second string. Accepting an Optional as the second arg would result in code like this:

foo("bar", Optional.of("baz"));
foo("bar", Optional.empty());

Even accepting null is nicer:

foo("bar", "baz");
foo("bar", null);

Probably the best is to have an overloaded method that accepts a single string argument and provides a default for the second:

foo("bar", "baz");
foo("bar");

This does have limitations, but it's much nicer than either of the above.

Use cases #3 and #4, having an Optional in a class field or in a data structure, is considered a misuse of the API. First, it goes against the main design goal of Optional as stated at the top. Second, it doesn't add any value.

There are three ways to deal with the absence of a value in an Optional: to provide a substitute value, to call a function to provide a substitute value, or to throw an exception. If you're storing into a field, you'd do this at initialization or assignment time. If you're adding values into a list, as the OP mentioned, you have the additional choice of simply not adding the value, thereby "flattening" out absent values.

I'm sure somebody could come up with some contrived cases where they really want to store an Optional in a field or a collection, but in general, it is best to avoid doing this.

Answer from Stuart Marks on Stack Overflow
🌐
Medium
medium.com › @alxkm › optional-in-java-best-practices-for-safer-code-3f4a3b80e122
Optional in Java: Best Practices for Safer Code. Java Interview | by Alex Klimenko | Medium
August 9, 2025 - Java's Optional is a powerful tool when used thoughtfully. It makes your code more robust, readable, and null-safe-but only if you follow best practices.
🌐
Baeldung
baeldung.com › home › java › core java › guide to java optional
Guide To Java Optional | Baeldung
February 15, 2026 - In this tutorial, we’re going ... in Java 8. The purpose of the class is to provide a type-level solution for representing optional values instead of null references. To get a deeper understanding of why we should care about the Optional class, take a look at the official Oracle article. Learn the best practices and when to ...
Discussions

java - Uses for Optional - Stack Overflow
Having been using Java 8 now for 6+ months or so, I'm pretty happy with the new API changes. One area I'm still not confident in is when to use Optional. I seem to swing between wanting to use it More on stackoverflow.com
🌐 stackoverflow.com
Optional Class in Java – A Comprehensive Tutorial
To be fair, i didnt read the whole article but i find the "best practices" and "Common pitfalls" sections to be lack luster. The "overuse of optional" and "use optional only when necessary" seam kind of obvious but its good to write it out. You shouldn't use optional values when the value isn't actually optional. "Avoid Using Optional in Fields or Parameters" why? I heard a senior of mine say a similar thing before and i didn't understand it then and still don't understand it now. Especially since doing exactly that in rust is not only fine but very common. "Returning Optional from Collections" this one i don't understand at all. Collections in Java are already defined interfaces and you couldn't make the `.get()` method return an option if you wanted to. So if im not implementing an existing collections interface, why shouldn't i return an option for those? The big issue for me is that optionals in java are not null safe. A method that returns an optional might not return a value at all but return null instead. So i *should* do a null check for that. Then i use the optional to check if the value is there or not. And then the value inside of the optional might also be null which i should do a null check on. So really if a method returns an optional i *should* check three times if the value is actually there or not. If it had just returned the value i only need to do one null check. Yes there are best practices to make sure that a variable of type Optional is never null. A method that returns optional should never return null and to never put null into an optional but man would it be nice if the language could just guarantee that from the start. More on reddit.com
🌐 r/programming
12
6
October 17, 2024
coding style - Java (or other Java-like languages): Best practice for many optional parameters? - Software Engineering Stack Exchange
Wish Java would get over itself and just add named arguments already. They make optional arguments so simple. Another best practice with optional args is to use good default values. Not setting an optional argument doesn't mean it has to be null. More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
November 7, 2019
Learn the pros and cons of upgrading from Java 8
Give this 45 minute talk a watch from GOTO Amsterdam 2019 by Trisha Gee, developer advocate & Java champion. You can find the full talk abstract below: Wasn’t Java 8 a fantastic update to the language? Lambdas and streams were a huge change and have helped to improve Java developers’ productivity and introduce some functional ideas to the language. Then came Java 9… and although the module system is really interesting for certain types of applications, the lack of exciting language features and uncertainty around how painful it might be to migrate to Java 9 left many applications taking a wait-and-see approach, happy with Java 8. But now Java has a new version every six months, and suddenly Java 12 is here. We’re all still on Java 8, wondering whether we should move to a later version, which one to choose, and how painful it might be to upgrade. In this session we’ll look at: Why upgrade from Java 8, including language features from Java 9, 10, 11 and 12 What sorts of issues might we run into if we do choose to upgrade How the support and license changes that came in with Java 11 might impact us. What will the audience learn from this talk? They'll learn the pros and cons of upgrading from Java 8. This includes not only the language features in the latest versions of Java (9, 10, 11 and 12), but some of the performance implications and, most importantly, the license changes and changes to support that might cost the audience money if they don't understand them. Does it feature code examples and/or live coding? Yes, both code examples on the slides and a bit of live coding. More on reddit.com
🌐 r/java
45
139
September 20, 2019
🌐
Medium
medium.com › @ayoubtaouam › using-optional-in-java-effectively-anti-patterns-and-best-practices-a11ec8fb4ac3
Using Optional in Java Effectively: Anti-Patterns and Best Practices
November 5, 2025 - Think of Optional not as a “null killer,” but as a way to communicate intent · “This value might not be here, and you should handle that gracefully.” ... If you enjoyed this article, follow me for more deep dives into Java and Spring Boot, explained simply.
🌐
GitHub
gist.github.com › carefree-ladka › cc6426829c8865a45f727db7368e94fe
Complete Java Optional Guide with Best Practices · GitHub
Optional.empty() // Empty Optional Optional.of(value) // ⚠️ Throws NPE if null Optional.ofNullable(value) // ✅ Safe, recommended · isPresent() // true if value present isEmpty() // true if empty (Java 11+)
🌐
Medium
medium.com › @alxkm › optional-in-java-768a5c1e0566
Optional in Java. Java Optional Best Practices, Pitfalls… | by Alex Klimenko | Medium
August 9, 2025 - Optional brought standardization-and safety-to an otherwise ad-hoc practice. Kotlin, like a younger sibling who watched their older brother's mistakes, embedded null-safety into the type system itself. val name: String? = user.name // The `?` denotes possible null val length = name?.length ?: 0 // Safe call and Elvis operator · With Kotlin, you can't even compile unsafe null access. The compiler guards your every move. In Java, Optional is not enforced.
🌐
Medium
medium.com › codimis › optional-best-practices-e561e0a6f684
Optional Best Practices.Learn when to use Optional | Codimis
March 22, 2024 - Let’s explore it with an example. If you want to retrieve your user data with the id field, there is a chance that the id value does not belong to any of the stored users. Hence, you can return a null user object. In that case, Optional is the best candidate as a return type.
🌐
Ducmanhphan
ducmanhphan.github.io › 2019-12-06-Best-practice-for-Optional-in-Java
Best practice for Optional in Java
December 6, 2019 - If we are using Optional like the above code, we can find that it is as same as when checking null value of Object variable. So, to reduce the boilerplate code, we can do like that. optName.ifPresent(realValue -> doSomething(realValue)); But in some cases, we can have an another action for some unsatisfied conditions, then we can use ifPresentOrElse() method. Below is a source code of ifPresentOrElse() method. // since Java 9 public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) { if (value != null) { action.accept(value); } else { emptyAction.run(); } }
Find elsewhere
Top answer
1 of 14
299

The main design goal of Optional is to provide a means for a function returning a value to indicate the absence of a return value. See this discussion. This allows the caller to continue a chain of fluent method calls.

This most closely matches use case #1 in the OP's question. Although, absence of a value is a more precise formulation than null since something like IntStream.findFirst could never return null.


For use case #2, passing an optional argument to a method, this could be made to work, but it's rather clumsy. Suppose you have a method that takes a string followed by an optional second string. Accepting an Optional as the second arg would result in code like this:

foo("bar", Optional.of("baz"));
foo("bar", Optional.empty());

Even accepting null is nicer:

foo("bar", "baz");
foo("bar", null);

Probably the best is to have an overloaded method that accepts a single string argument and provides a default for the second:

foo("bar", "baz");
foo("bar");

This does have limitations, but it's much nicer than either of the above.

Use cases #3 and #4, having an Optional in a class field or in a data structure, is considered a misuse of the API. First, it goes against the main design goal of Optional as stated at the top. Second, it doesn't add any value.

There are three ways to deal with the absence of a value in an Optional: to provide a substitute value, to call a function to provide a substitute value, or to throw an exception. If you're storing into a field, you'd do this at initialization or assignment time. If you're adding values into a list, as the OP mentioned, you have the additional choice of simply not adding the value, thereby "flattening" out absent values.

I'm sure somebody could come up with some contrived cases where they really want to store an Optional in a field or a collection, but in general, it is best to avoid doing this.

2 of 14
139

I'm late to the game but for what it's worth, I want to add my 2 Cents. They go against the design goal of Optional, which is well summarized by Stuart Marks's answer, but I'm still convinced of their validity (obviously).

Use Optional Everywhere

In General

I wrote an entire blog post about using Optional but it basically comes down to this:

  • design your classes to avoid optionality wherever feasibly possible
  • in all remaining cases, the default should be to use Optional instead of null
  • possibly make exceptions for:
    • local variables
    • return values and arguments to private methods
    • performance critical code blocks (no guesses, use a profiler)

The first two exceptions can reduce the perceived overhead of wrapping and unwrapping references in Optional. They are chosen such that a null can never legally pass a boundary from one instance into another.

Note that this will almost never allow Optionals in collections which is almost as bad as nulls. Just don't do it. ;)

Regarding your questions

  1. Yes.
  2. If overloading is no option, yes.
  3. If other approaches (subclassing, decorating, ...) are no option, yes.
  4. Please no!

Advantages

Doing this reduces the presence of nulls in your code base, although it does not eradicate them. But that is not even the main point. There are other important advantages:

Clarifies Intent

Using Optional clearly expresses that the variable is, well, optional. Any reader of your code or consumer of your API will be beaten over the head with the fact that there might be nothing there and that a check is necessary before accessing the value.

Removes Uncertainty

Without Optional the meaning of a null occurrence is unclear. It could be a legal representation of a state (see Map.get) or an implementation error like a missing or failed initialization.

This changes dramatically with the persistent use of Optional. Here, already the occurrence of null signifies the presence of a bug. (Because if the value were allowed to be missing, an Optional would have been used.) This makes debugging a null pointer exception much easier as the question of the meaning of this null is already answered.

More Null Checks

Now that nothing can be null anymore, this can be enforced everywhere. Whether with annotations, assertions or plain checks, you never have to think about whether this argument or that return type can be null. It can't!

Disadvantages

Of course, there is no silver bullet...

Performance

Wrapping values (especially primitives) into an extra instance can degrade performance. In tight loops this might become noticeable or even worse.

Note that the compiler might be able to circumvent the extra reference for short lived lifetimes of Optionals. In Java 10 value types might further reduce or remove the penalty.

Serialization

Optional is not serializable but a workaround is not overly complicated.

Invariance

Due to the invariance of generic types in Java, certain operations become cumbersome when the actual value type is pushed into a generic type argument. An example is given here (see "Parametric polymorphism").

🌐
Dariawan
dariawan.com › tutorials › java › using-java-optional-correctly
Using Java Optional Correctly | Dariawan
In a way, it replaces null, and when Optional is in use, there should never be a question of returning or receiving null from a call. import java.util.Optional; import javax.annotation.Nullable; public class NullNoncompliant { public void ...
🌐
LinkedIn
linkedin.com › pulse › navigating-java-optional-best-practices-anti-patterns-shivam-kumar-lbqif
"Navigating the Java Optional: Best Practices and Anti-patterns"
November 1, 2023 - Understanding the Purpose of Optional ... for handling nullable values. Best Practices for Using Optional:Proper use cases and scenarios where Optional is beneficial.Mapping, filtering, and transforming with Optional to streamline ...
🌐
DZone
dzone.com › coding › languages › java 8 optional usage and best practices
Java 8 Optional Usage and Best Practices
July 2, 2019 - If you are new to Java 8, then you are probably wondering: What is a consumer? Well, in simple terms, a consumer is a method that accepts an argument and does not return anything. When using ifPresent, this looks like killing two birds with one stone. We can do a value presence check and perform the intended operation with one method, as shown below. //ifpresent Optional<String> optional1 = Optional.of("javaone"); optional1.ifPresent(s -> System.out.println(s.length()));
🌐
DEV Community
dev.to › ivangavlik › how-to-use-the-optional-class-java-3pf5
How to use Optional class (Java) - best practices - DEV Community
January 27, 2024 - Optional is limited mechanism for ... For example, you probably should never use it for something that returns an array of results, or a list of results; instead return an empty array or list....
🌐
GitConnected
levelup.gitconnected.com › how-to-use-optionals-correctly-in-java-must-know-dos-and-don-ts-2bbd8433a06a
How to Use Optionals Correctly in Java — Must-know do’s and don’ts. | by Sarangan Janakan | Level Up Coding
April 9, 2025 - Java’s Optional<T> is a powerful feature introduced in Java 8 to help developers avoid NullPointerException issues by explicitly handling the absence of a value · This article explains how we should use Optional and avoid anti-patterns and provides best practices for handling optional values ...
🌐
Javacodehouse
javacodehouse.com › blog › java-optional-use
Java Optional | How and When to use it
Optional is a powerful tool for expressing optional values more clearly and avoiding null pointer exceptions. However, it should be used judiciously, and developers should be mindful of its appropriate application to avoid unnecessary complexity in the code. Tired of Null Pointer Exceptions? Consider Using Java SE 8’s Optional!
🌐
Reddit
reddit.com › r/programming › optional class in java – a comprehensive tutorial
r/programming on Reddit: Optional Class in Java – A Comprehensive Tutorial
October 17, 2024 - So really if a method returns an ... i only need to do one null check. Yes there are best practices to make sure that a variable of type Optional is never null....
🌐
Medium
rohitchavan8058.medium.com › mastering-java-optional-best-practices-for-safer-and-cleaner-code-f19b68b94146
Mastering Java Optional: Best Practices for Safer and Cleaner Code | by Rohit Chavan | Medium
February 9, 2024 - Rule #5: Untangle Nested Optional Chains Avoid the complexity introduced by nested Optional types or intermediate results of Optional<Optional<T>>. Refactor your code to simplify logic and enhance understandability.
🌐
Coding Shuttle
codingshuttle.com › home › blogs › mastering optional in java: avoid nullpointerexceptions with best practices
Mastering Optional in Java: Avoid NullPointerExceptions with Best Practices | Coding Shuttle
February 27, 2026 - List<Optional<String>> names = getNames(); List<String> validNames = names.stream() .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()); Use orElseGet for Expensive Defaults: Prefer orElseGet over orElse when the default value is computationally expensive. Java’s Optional class is a game-changer for writing robust, null-safe code.
🌐
DevGenius
blog.devgenius.io › cleaner-code-with-java-optional-examples-best-practices-and-exercises-005f2a9a6a7d
Cleaner Code with Java Optional: Examples, Best Practices and Exercises | by Ani Talakhadze | Dev Genius
October 28, 2024 - What if I told you there’s a better way? Java’s Optional class not only cleans up code but enforces better practices, making value presence (or absence) explicit.
🌐
The Java Bootcamp
javapro.academy › home › java blog › core java bootcamp › mastering optional in java 8: a comprehensive guide
Mastering optional in Java 8: A Comprehensive Guide – The Java Bootcamp
October 9, 2025 - This is particularly useful for validating values or implementing business rules without breaking the Optional chain or resorting to external if statements. Collection Handling Best Practices: When working with collections, return empty collections rather than Optional<Collection>. This simplifies the code as empty collections already represent the absence of values and can be safely iterated over.