Oh, those coding styles are to be taken with a bit of salt.

  1. (+) Passing an Optional result to another method, without any semantic analysis; leaving that to the method, is quite alright.
  2. (-) Using Optional parameters causing conditional logic inside the methods is literally contra-productive.
  3. (-) Needing to pack an argument in an Optional, is suboptimal for the compiler, and does an unnecessary wrapping.
  4. (-) In comparison to nullable parameters Optional is more costly.
  5. (-) The risk of someone passing the Optional as null in actual parameters.

In general: Optional unifies two states, which have to be unraveled. Hence better suited for result than input, for the complexity of the data flow.

Answer from Joop Eggen on Stack Overflow
Top answer
1 of 16
376

Oh, those coding styles are to be taken with a bit of salt.

  1. (+) Passing an Optional result to another method, without any semantic analysis; leaving that to the method, is quite alright.
  2. (-) Using Optional parameters causing conditional logic inside the methods is literally contra-productive.
  3. (-) Needing to pack an argument in an Optional, is suboptimal for the compiler, and does an unnecessary wrapping.
  4. (-) In comparison to nullable parameters Optional is more costly.
  5. (-) The risk of someone passing the Optional as null in actual parameters.

In general: Optional unifies two states, which have to be unraveled. Hence better suited for result than input, for the complexity of the data flow.

2 of 16
237

The best post I've seen on the topic was written by Daniel Olszewski:

Although it might be tempting to consider Optional for not mandatory method parameters, such a solution pale in comparison with other possible alternatives. To illustrate the problem, examine the following constructor declaration:

Copypublic SystemMessage(String title, String content, Optional<Attachment> attachment) {
    // assigning field values
}

At first glance it may look as a right design decision. After all, we explicitly marked the attachment parameter as optional. However, as for calling the constructor, client code can become a little bit clumsy.

CopySystemMessage withoutAttachment = new SystemMessage("title", "content", Optional.empty());
Attachment attachment = new Attachment();
SystemMessage withAttachment = new SystemMessage("title", "content", Optional.ofNullable(attachment));

Instead of providing clarity, the factory methods of the Optional class only distract the reader. Note there’s only one optional parameter, but imagine having two or three. Uncle Bob definitely wouldn’t be proud of such code 😉

When a method can accept optional parameters, it’s preferable to adopt the well-proven approach and design such case using method overloading. In the example of the SystemMessage class, declaring two separate constructors are superior to using Optional.

Copypublic SystemMessage(String title, String content) {
    this(title, content, null);
}

public SystemMessage(String title, String content, Attachment attachment) {
    // assigning field values
}

That change makes client code much simpler and easier to read.

CopySystemMessage withoutAttachment = new SystemMessage("title", "content");
Attachment attachment = new Attachment();
SystemMessage withAttachment = new SystemMessage("title", "content", attachment);
🌐
Reddit
reddit.com › r/java › opinions on using optional as parameter
r/java on Reddit: Opinions on using Optional<> as parameter
January 23, 2022 -

I like using Optional<> to return values that may be null but today I saw people using them to accept parameters that may be null, if the parameter wasn't an Optional<> then it couldn't be null. I personally don't like doing that but I'd like to hear some opinions.

They were doing things like

double getStartingBalance(@NotNull Optional<UUID> user) { ... }

In my opinion, Optional<> is used to force the developer to handle null values. If my method is called and may return null, I'll return an Optional<> to make sure that null is handled but if I design the method and define that something cannot be null I can just use Objects#requereNonNull or if it can be null a simple check does the job. Also having to box values in optionals and having to use Optional.empty() for nulls to call a method is messy and makes the call harder to read.

So what are your opinions on using optionals as parameters?

🌐
Medium
medium.com › @yassinhajaj › optionals-are-bad-practices-still-bad-practices-if-everyone-practices-them-6ec5a66c30aa
Optionals : are bad practices still bad practices if everyone practices them ? | by Yassin Hajaj | Medium
July 8, 2019 - 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 ...
🌐
Stackify
stackify.com › optional-parameters-java
Optional Parameters in Java: Strategies and Approaches-Stackify
April 10, 2024 - It’s typically a bad idea to allow method callers to supply null values and this widely considered an anti-pattern. For the sake of demonstration, let’s see what this looks like in practice: MultiVitaminAllowingNulls vitamin = new ...
🌐
Quora
quora.com › Why-is-using-java-util-Optional-as-a-method-parameter-not-recommended
Why is using java.util.Optional as a method parameter not recommended? - Quora
Answer (1 of 2): Since Optional class was introduced in Java 8, It just acts as a container for NULL references and used to avoid NullPointerException . Problems: 1. You are making one more object in your heap just to store the NULL reference and now you have two objects in your heap for the sa...
🌐
Codemia
codemia.io › knowledge-hub › path › why_should_java_8s_optional_not_be_used_in_arguments
Why should Java 8's Optional not be used in arguments
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
🌐
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 - In this article, we saw the definitions of a Java record and understood the importance of transparency and immutability. We also looked at the intended usage of the Optional class. More importantly, we discussed that Optionals are not suitable to be used as record parameters.
Find elsewhere
🌐
nipafx
nipafx.dev › inside-java-newscast-19
Where to use Optional - Inside Java Newscast #19 - nipafx.dev
This doesn't happen often, but if it does, it's really bad - so much worse than a bunch of Optional.ofNullable. And very annoying if they already have Optionals on their hand, because they'll probably be wondering why they can't just pass those on - I know I do. A recurring recommendation to avoid the combinatorial explosion of overloads is to use the builder pattern for constructors and to create a parameter object for methods.
Published   January 27, 2022
🌐
freeCodeCamp
freecodecamp.org › news › optional-in-java-and-anti-patterns-using-it-7d87038362ba
A look at the Optional datatype in Java and some anti-patterns when using it
April 12, 2019 - Another pattern we encountered, especially when code is getting migrated from the “old-fashioned” way of using a null-reference to using the optional-type, is having optional-typed parameters in function-definitions. This typically happens if you find a function that does null-checks on its parameters and applies different behaviour then — which, in my opinion, was bad-practice before anyways.
🌐
Dariawan
dariawan.com › tutorials › java › using-java-optional-correctly
Using Java Optional Correctly | Dariawan
Actually this is one of the rule of thumb that quite often voided by Java Programmer (including myself and some samples in this site). The issue is, Optional class is definitively not intended for use as a property of a Java Bean.
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).

🌐
Medium
medium.com › @alxkm › optional-in-java-768a5c1e0566
Optional in Java. Java Optional Best Practices, Pitfalls… | by Alex Klimenko | Medium
August 9, 2025 - Return Optional from methods where null might otherwise be returned. Never use Optional for fields or serialization. Avoid using Optional in method parameters-use overloads or builders instead.
🌐
Baeldung
baeldung.com › home › java › core java › guide to java optional
Guide To Java Optional | Baeldung
February 15, 2026 - The intent of Java when releasing ... return an empty value. As a matter of fact, the practice of using Optional as a method parameter is even discouraged by some code inspectors....
🌐
Medium
medium.com › codimis › optional-best-practices-e561e0a6f684
Optional Best Practices.Learn when to use Optional | Codimis
March 22, 2024 - Java introduced a game-changer with the advent of Java 8, the Optional class. Optional was designed to address a long-standing problem: handling of potentially null values. In this article, we will explore the best practices and bad practices of Java Optional to help you to understand when ...
🌐
DZone
dzone.com › articles › optional-method-parameters
Optional Method Parameters
February 28, 2017 - This, depending on the case might be a good thing or a bad thing. That’s a quote from another StackOverflow answer. I’d say that it can be an argument against Optional in general, but not solely against Optional arguments, as you can return a null instead of Optional, too. As a general argument, it still seems weak, as we’re not talking about a dangerous toy for a kid, we’re talking about programmers (smart guys, you know?). If we followed this logic, we’d have to say that using Java is unsafe as you can do almost anything via reflection.
Top answer
1 of 1
5

In general, Optional has a restricted set of use cases and is in danger of being overrused. You can refer to this answer by Java author Brian Goetz to understand these (emphasis added):

But we did have a clear intention when adding this [java.util.Optional] 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.

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.

In the original example posted, Optional<Y> is used as a method parameter so this is against Java best practices. Besides, Maybe is idiomatic in RxJava.

Assuming you have something like the following:

class X
class Y
data class DataContent constructor(val listOfX: List<X>, val y: Y)

You could write a function like this that would seem to fit your use case:

fun zipToDataContent(maybeListOfX: Maybe<List<X>>, maybeY: Maybe<Y>): Maybe<DataContent> =
        Maybe.zip<List<X>, Y, DataContent>(
                maybeListOfX,
                maybeY,
                BiFunction { listOfX, y -> DataContent(listOfX, y) })

Tests:

@Test
fun testZipToDataContentWithRealY() {
    val x = X()
    val y = Y()

    val maybeListOfX = Maybe.just(listOf(x))
    val maybeY = Maybe.just(y)

    zipToDataContent(maybeListOfX, maybeY).test()
            .assertOf {
                Maybe.just(DataContent(listOf(x), y))
            }
}

@Test
fun testZipToDataContentWithEmptyY() {
    val x = X()

    val maybeListOfX = Maybe.just(listOf(x))
    val maybeY = Maybe.empty<Y>()

    zipToDataContent(maybeListOfX, maybeY).test()
            .assertOf {
                Maybe.empty<DataContent>()
            }
}
Top answer
1 of 2
7

One reason is that conceptually, firstName, middleName, and lastName are logically one argument, not three. They're all parts of a bigger whole, and one can imagine that they're almost always passed together. In functional languages they'd likely be passed as a tuple or record; Java lacks those, so they'd probably be aggregated into a Name class. Note that if you needed to compose functions that take and return full names, you wouldn't be able to without aggregating them - you can only return one value, after all.

Maybe it just doesn't come up very often that a value is optional and also not part of a bigger whole. If the function requires a certain value to do its work, then that function shouldn't be accepting an Optional. If you need to chain operations that might not return a value, aborting with Nothing if any function along the way fails, you can chain calls to flatMap, and if you want to fail with an exception you can use get() at any step of the way or at the end of the chain.

If a value is truly optional and a function does two different things based on its presence or absence, that's a code smell unless the function is a wrapper of two smaller functions that do one thing each, and that particular combination of decisions is very common.

I don't think it's so much that it's wrong as it is a relatively uncommon use case.

2 of 2
5

There aren't very many languages that don't support default arguments, so this is not a common usage. I personally think your usage isn't terrible, but it's not going to be idiomatic Java. Java very intentionally doesn't have default arguments, to force the use of overloading instead, which has the advantage of the compiler checking your arguments instead of requiring if statements inside the function.

In other words, you're going to be making two different versions of the query: one with a middle name and one without. If you can do that in a concise way, using an option is a good idea. If it's verbose enough that you'd want it in two separate functions anyway, you may as well use the overloading and make it idiomatic.