Java 8's Optional was mainly intended for return values from methods, and not for properties of Java classes, as described in Optional in Java SE 8:

Of course, people will do what they want. But we did have a clear intention when adding this feature, and it was not to be a general purpose Maybe or Some type, as much as many people would have liked us to do so. Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent "no result", and using null for such was overwhelmingly likely to cause errors.

The key here is the focus on use as a return type. The class is definitively not intended for use as a property of a Java Bean. Witness to this is that Optional does not implement Serializable, which is generally necessary for widespread use as a property of an object.

Answer from Jesper on Stack Overflow
🌐
Baeldung
baeldung.com › home › java › core java › guide to java optional
Guide To Java Optional | Baeldung
February 15, 2026 - Optional makes us deal with nullable values explicitly as a way of enforcing good programming practices. Let’s now look at how the above code could be refactored in Java 8.
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › Optional.html
Optional (Java Platform SE 8 )
April 21, 2026 - If a value is present the result must include its string representation in the result. Empty and present Optionals must be unambiguously differentiable. ... Java™ Platform Standard Ed.
🌐
Reddit
reddit.com › r/learnjava › why is it considered "bad practice" to use optional as the type of member variables?
r/learnjava on Reddit: Why is it considered "Bad Practice" to use Optional as the type of member variables?
February 21, 2020 -

Hello everyone!

My question is basically the title. I wonder why you are discouraged to use Optional and its derivatives as the type of member variables. When using an IDE like IntelliJ or reading blogs on the internet, everyone discourages you of using Optional as a member variable. From what I can see, there are mostly two reasons mentioned for this:

  1. The first argument brought up is, that Optional is not Serializable. So an Object which has a member of type Optional, is not Serializable as well. At least you can't simply make it Serializable using the default implementation.

I understand why this could be a problem. You can't just simply implement the Serializable interface and are done. But as always you could simply override the default serialization process or choose not to serialize the Optional field by marking it as transient. The ArrayList implementation for example does the same as its contents aren't guaranteed to be Serializable. In my opinion, this argument is somewhat valid, but its not a reason to actively discourage the use of Optional. Especially since serialization in Java does have much more pitfalls.

2. The other argument I see, is that Optional was not designed to be used in this way. Apparently Optional is only "a limited mechanism to represent a method may have no result".

But in this case, I don't see a reason, why it should only be limited to the return type of methods. By using Optional as the type of a member variable, you can also communicate, that this field is not always present and have much less trouble with null values and checking for them.

I could see, that it's "more the Java way", to use null whenever some value is not present. But due to the way Java works, this is only possible for non-primitive member variables. If you were to use OptionalInt or OptionalLong, there is no good primitive alternative. In some cases, you could communicate a missing value using 0 or negative numbers, but perhaps this could be a valid value as well, making it even harder to check, whether the value is present. In this cases you could either use the boxed variant of int and long or you could use some magic constants to communicate a missing values in hope, the chosen value will never be a real result. Using the boxed variant of primitives seems like the better alternative here, but it is not optimal, since boxing not only costs performance, it will also give you confusing error messages, if Java tries to unbox a null value.

This is my point of view on this topic. Feel free to add you own opinion or perhaps resources, that explain why using Optional is a bad idea for member variables. I really hope to understand, why this decision was made in Java.

Top answer
1 of 2
13
See this answer by Brian Goetz: https://stackoverflow.com/a/26328555/276052 Of course, people will do what they want. But we did have a clear intention when adding this feature, and it was not to be a general purpose Maybe type, as much as many people would have liked us to do so. Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent "no result", and using null for such was overwhelmingly likely to cause errors. 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. You should almost never use it as a field of something or a method parameter. I think routinely using it as a return value for getters would definitely be over-use. There's nothing wrong with Optional that it should be avoided, it's just not what many people wish it were, and accordingly we were fairly concerned about the risk of zealous over-use. Basically there's nothing wrong with using it per see, but it doesn't magically solve your problems. An empty optional is just as tricky to deal with as a null value. It's just more obvious at compile time that you have to deal with it. So where it's important to signal this (return types of API methods for example) it's quite useful, but for internal variables it mostly just adds wrapping/unwrapping overhead to your code.
2 of 2
2
You want to avoid cluttering your class with too many Optional attributes because it allows you so much flexibility that you risk your object trying to do multiple things, and that is just not clean code. Your class becomes this weird monster do all class and your code becomes unreadable, tightly coupled with state (optionals are empty or not), and incredibly difficult to maintain. If you have too many optionals in your class, you probably need to break it out into multiple classes and use inheritance and/or polymorphism.
Top answer
1 of 4
5

Whether something is "OK to use" depends on intent, team coding practices, common programming idioms, and how strictly you want to adhere to API guidelines.

First, the facts about Optional<T>:

A container object which may or may not contain a non-null value.

...

API Note:

Optional is primarily intended for use as a method return type where there is a clear need to represent "no result," and where using null is likely to cause errors. A variable whose type is Optional should never itself be null; it should always point to an Optional instance.

Source: Oracle Java 11 JDK documentation (emphasis, mine)

Not a lot of concrete guidance here beyond the recommendation that Optional<T> be used as a return type. In a strict sense, you are not using this as a return type, therefore the answer is "no, this is not OK." On the other hand, you are using it as the type for a field which may contain null. So you seem to satisfy the first part.

But it works.

That's why it's important to remember these are guidelines. The mechanics of whether you can use something are a different discussion, and hence, your question. Instead, I like to see how these optional fields are being used to ensure a more suitable OO design doesn't already exist.

If I had to look at a codebase that was peppered with field.ifPresent(foo -> foo.method()) every time field was used, I would start to wonder if we have a design problem with field rather than it's type. Even in cases where you have field.isPresentOrElse(foo -> foo.method(), () -> something else), I still think we are missing something. Frankly, the constant calls to the Optional<T> methods as a round-about way to avoid NullPointerExceptions makes me think the Null Object Pattern might be a better choice here. Every method in the "null object" can be a no-op. Getters can return pre-canned values (whatever the "or else" part of Optional.ifPresentOrElse() would have returned).

I don' like optional dependencies because they can be null, so now I need to incessantly check for null, or I need to use some other non-idiomatic construct like Optional<T> with a bunch of pass-through method calls in lieu of null-checks.

Code is much cleaner if you can simply call field.method() rather than field.ifPresent(foo -> foo.method()).

Some additional notes:

  • The guidance in this answer applies best to situations where the T is a complex type. When T is a string, boolean, or numeric type, then the "optional" part of an Optional<T> becomes meaningful. An Optional<boolean> can be true, false, or not present, which your application could interpret as "not specified." In that case, document this fact on the field.

    • In the case of a String, consider defaulting to an empty string instead. No need for null if you have proper encapsulation. A constructor or setter can enforce the "empty string instead of null" constraint.
  • When T is a complex type, consider other, more straight-forward designs first before resorting to an Optional<T>, if for no other reason than the Principle of Least Astonishment.

  • Choose code that is easy to read first. In situations like this, I like to write the same code multiple ways. Consider writing it when checking for nulls, using another more suitable design pattern (like Null Object Pattern), and using an optional. Same code. 3 different styles. Which one do you like?

    • And then present the same 3 styles to a colleague to see which one they like.

In the end, you get working code either way. Personal taste, other object-oriented design practices and team habits play a bigger role in this decision than API guidance.

2 of 4
5

Optional is now intended to be used as a Monad. Java designers effectively admitted that by adding Optional.stream() method.

Ignore earlier discussions about:

  • serialization. Serialization should not be used in new code
  • library interfaces. They are not different from your own.
  • method argument. Using Optional as argument in much more idiomatic than doing a conditional dispatch over method overloads.

Surprisingly, important reasons not to use an Optional as a field are:

  • memory consumption - it increases the size of your field up to 4 times.
  • performance - it introduces additional memory indirection

These are only applicable to long-lived numerous objects (example: gamedev).

🌐
Stack Abuse
stackabuse.com › guide-to-optional-in-java-8
Guide to Using Optional in Java 8
February 21, 2020 - Notice how this is quite helpful since we don't have semantic meanings of this kind with regular attribute definitions. In this section, we'll take a bit of time to explain the previous example with flatMaps and maps. If you understand it without further explanation, please feel free to skip this section. The first method call is performed on falcon which is of type Optional<Spaceship>. Calling the getEngine method returns an object of type Optional<Engine>. Combining these two types, the type of the returned object becomes Optional<Optional<Engine>>.
Find elsewhere
🌐
HowToDoInJava
howtodoinjava.com › home › java 8 › guide to java 8 optional
Java 8 Optional (with Examples) - HowToDoInJava
February 7, 2023 - If we open the source code of Optional.java, we will find that value that Optional holds is defined as: /** * If non-null, the value; if null, indicates no value is present */ private final T value; When we create an Optional then the below call happens at the end and assigns the passed value to ‘value‘ attribute...
🌐
GeeksforGeeks
geeksforgeeks.org › java › java-8-optional-class
Java 8 Optional Class - GeeksforGeeks
May 16, 2026 - Optional.of(value): Returns an Optional containing the given non-null value. ... import java.util.Optional; class GFG { public static void main(String[] args) { String[] str = new String[5]; str[2] = "Geeks Classes are coming soon"; Optional<String> empty = Optional.empty(); System.out.println(empty); Optional<String> value = Optional.of(str[2]); System.out.println(value); } }
🌐
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 library method return types where there needed to be a clear way to represent "no result", and using null for such was overwhelmingly likely to cause errors.
🌐
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 - Traditionally, null values in Java have led to countless NullPointerExceptions, often in places where the absence of a value wasn't clearly indicated. Optional makes it explicit when a value might be missing, promoting better readability and safer code.
🌐
DEV Community
dev.to › piczmar_0 › java-optional-in-class-fields-why-not-40df
Java Optional in class fields? Why not. - DEV Community
October 26, 2018 - Optional was introduced in Java 8 and according to documentation it is supposed to limit the use of null in return from the methods.
🌐
Thorben Janssen
thorben-janssen.com › use-java-8-optional-hibernate
How to use Java 8's Optional with Hibernate
October 17, 2022 - Java 8 introduced Optional<T> as a container object which may contain null values. It’s often used to indicate to a caller that a value might be null and that it need to be handled to avoid NullPointerExceptions.
🌐
Stackify
stackify.com › optional-parameters-java
Optional Parameters in Java: Strategies and Approaches-Stackify
April 10, 2024 - In this article, we’ve looked at a variety of strategies for working with optional parameters in Java, such as method overloading, the builder pattern, and the ill-advised strategy of allowing callers to supply null values.
🌐
Developer.com
developer.com › dzone › coding › java › how to use optionals in java
How to Use Optionals in Java
December 8, 2023 - Instead, we need a mechanism that allows a method developer to explicitly denote that the return value for a method may or may not be present. This mechanism was introduced in Java Development Kit (JDK) 7 in the form of the Optional class.
🌐
Oracle
docs.oracle.com › en › java › javase › 24 › docs › api › java.base › java › util › class-use › Optional.html
Uses of Class java.util.Optional (Java SE 24 & JDK 24)
July 15, 2025 - Methods in java.lang.classfile that return Optional ... Returns the class bound of the type parameter. ... Returns the body of this method, if there is one. ... Finds an attribute by name.
🌐
Tom Gregory
tomgregory.com › java-optional
Optional in Java: Everything You Need To Know | Tom Gregory
July 17, 2022 - My glasses case is a kind of container, just like Optional · Amazing, I know! In Java we create an Optional with a specific state.
🌐
Baeldung
baeldung.com › home › java › core java › optional as a record parameter in java
Optional as a Record Parameter in Java | Baeldung
January 16, 2024 - And getting the exception is sometimes used to identify the absence of value. The main goal of Optional is to represent a method return value that represents the absence of a value.