There are several ways to simulate optional parameters in Java.

Method overloading

Copyvoid foo(String a, Integer b) {
    //...
}

void foo(String a) {
    foo(a, 0); // here, 0 is a default value for b
}

foo("a", 2);
foo("a");

One of the limitations of this approach is that it doesn't work if you have two optional parameters of the same type and any of them can be omitted.

Varargs

a) All optional parameters are of the same type:

Copyvoid foo(String a, Integer... b) {
    Integer b1 = b.length > 0 ? b[0] : 0;
    Integer b2 = b.length > 1 ? b[1] : 0;
    //...
}

foo("a");
foo("a", 1, 2);

b) Types of optional parameters may be different:

Copyvoid foo(String a, Object... b) {
    Integer b1 = 0;
    String b2 = "";
    if (b.length > 0) {
      if (!(b[0] instanceof Integer)) { 
          throw new IllegalArgumentException("...");
      }
      b1 = (Integer)b[0];
    }
    if (b.length > 1) {
        if (!(b[1] instanceof String)) { 
            throw new IllegalArgumentException("...");
        }
        b2 = (String)b[1];
        //...
    }
    //...
}

foo("a");
foo("a", 1);
foo("a", 1, "b2");

The main drawback of this approach is that if optional parameters are of different types you lose static type checking. Furthermore, if each parameter has the different meaning you need some way to distinguish them.

Nulls

To address the limitations of the previous approaches you can allow null values and then analyze each parameter in a method body:

Copyvoid foo(String a, Integer b, Integer c) {
    b = b != null ? b : 0;
    c = c != null ? c : 0;
    //...
}

foo("a", null, 2);

Now all arguments values must be provided, but the default ones may be null.

Optional class

This approach is similar to nulls, but uses Java 8 Optional class for parameters that have a default value:

Copyvoid foo(String a, Optional<Integer> bOpt) {
    Integer b = bOpt.isPresent() ? bOpt.get() : 0;
    //...
}

foo("a", Optional.of(2));
foo("a", Optional.<Integer>absent());

Optional makes a method contract explicit for a caller, however, one may find such signature too verbose.

Update: Java 8 includes the class java.util.Optional out-of-the-box, so there is no need to use guava for this particular reason in Java 8. The method name is a bit different though.

Builder pattern

The builder pattern is used for constructors and is implemented by introducing a separate Builder class:

Copyclass Foo {
    private final String a; 
    private final Integer b;

    Foo(String a, Integer b) {
      this.a = a;
      this.b = b;
    }

    //...
}

class FooBuilder {
  private String a = ""; 
  private Integer b = 0;
  
  FooBuilder setA(String a) {
    this.a = a;
    return this;
  }

  FooBuilder setB(Integer b) {
    this.b = b;
    return this;
  }

  Foo build() {
    return new Foo(a, b);
  }
}

Foo foo = new FooBuilder().setA("a").build();

Maps

When the number of parameters is too large and for most of the default values are usually used, you can pass method arguments as a map of their names/values:

Copyvoid foo(Map<String, Object> parameters) {
    String a = ""; 
    Integer b = 0;
    if (parameters.containsKey("a")) { 
        if (!(parameters.get("a") instanceof Integer)) { 
            throw new IllegalArgumentException("...");
        }
        a = (Integer)parameters.get("a");
    }
    if (parameters.containsKey("b")) { 
        //... 
    }
    //...
}

foo(ImmutableMap.<String, Object>of(
    "a", "a",
    "b", 2, 
    "d", "value")); 

In Java 9, this approach became easier:

Copy@SuppressWarnings("unchecked")
static <T> T getParm(Map<String, Object> map, String key, T defaultValue) {
  return (map.containsKey(key)) ? (T) map.get(key) : defaultValue;
}

void foo(Map<String, Object> parameters) {
  String a = getParm(parameters, "a", "");
  int b = getParm(parameters, "b", 0);
  // d = ...
}

foo(Map.of("a","a",  "b",2,  "d","value"));

Please note that you can combine any of these approaches to achieve a desirable result.

Answer from Vitalii Fedorenko on Stack Overflow
🌐
Reddit
reddit.com › r/java › named and optional parameters in java 17 - redefined version
r/java on Reddit: Named and Optional Parameters in Java 17 - Redefined Version
January 15, 2023 - It took me some time to make it work well, but in short here the issues that the compiler found previously related to the illegal syntax of named parameters and default values inside \@Option are marked as resolved in the Diagnostics. If for example the wrong types, unknown named parameters, ... are used to call a method or a class they are still reported by Javac normally.
🌐
GitHub
github.com › Auties00 › NamedParameters
GitHub - Auties00/NamedParameters: Named and Optional parameters for Java 17 · GitHub
If you want to make a parameter optional, you can do so by applying the @Option annotation:
Starred by 44 users
Forked by 4 users
Languages   Java
Discussions

How do I use optional parameters in Java? - Stack Overflow
Personaly I would prefer if they ... parameters. 2018-12-30T16:31:11.087Z+00:00 ... @Dherik The linked answer suggests that overloading should be used. In many cases, overloading is not a real option. Imagine that you have 5 params and each is optional. You would need 25 separate constructors to achieve that with overloading! I am guessing that many who end up here are trying to avoid this. I know I am. 2021-07-18T00:17:12.653... More on stackoverflow.com
🌐 stackoverflow.com
How do I make parameters optional?
Please ensure that: Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions You include any and all error messages in full You ask clear questions You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions. Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar If any of the above points is not met, your post can and will be removed without further warning. Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://i.imgur.com/EJ7tqek.png ) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc. Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit. Code blocks look like this: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above. If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures. To potential helpers Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns. More on reddit.com
🌐 r/javahelp
7
2
August 31, 2023
java - Are Optional fields okay? - Software Engineering Stack Exchange
Some fields may be optional. That is, a value doesn't have to be ever assigned to it. Luckily, Java has a special null-safer type for optional values — Optional However, if I try to make a field of... More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
September 27, 2024
Why exactly does Brian Goetz not recommend the use of Optional everywhere a value could be null?
The idea with Optional is to force the user of the method to handle the output straight away. Being able to pass that value around is against the point of using an Optional in the first place. For example, you have a method that calls an API. If it returns empty, you should either throw an exception, or fill in some default value. If it returns a value, then unpack it. You should not have an Optional going forward. More on reddit.com
🌐 r/java
285
123
June 2, 2023
🌐
Oracle
docs.oracle.com › en › java › javase › 17 › docs › api › java.base › java › util › Optional.html
Optional (Java SE 17 & JDK 17)
April 21, 2026 - java.util.Optional<T> Type Parameters: T - the type of value · public final class Optional<T> extends Object · A container object which may or may not contain a non-null value. If a value is present, isPresent() returns true. If no value is present, the object is considered empty and isPresent() ...
🌐
Baeldung
baeldung.com › home › java › core java › guide to java optional
Guide To Java Optional | Baeldung
February 15, 2026 - The orElse() method is used to retrieve the value wrapped inside an Optional instance. It takes one parameter, which acts as a default value.
🌐
Oracle
docs.oracle.com › en › java › javase › 17 › docs › api › java.base › java › util › class-use › Optional.html
Uses of Class java.util.Optional (Java SE 17 & JDK 17)
April 21, 2026 - If a value is present, returns an Optional describing the value, otherwise returns an Optional produced by the supplying function. Method parameters in java.util with type arguments of type Optional
🌐
FavTutor
favtutor.com › blogs › java-optional-parameters
Optional Parameters in Java Explained (with code)
August 23, 2023 - In some scenarios, while defining the method, we don't know the exact number of parameters that the user can provide to the function. In such cases, we opt for java optional parameters which take parameters as optional.
Top answer
1 of 16
1975

There are several ways to simulate optional parameters in Java.

Method overloading

Copyvoid foo(String a, Integer b) {
    //...
}

void foo(String a) {
    foo(a, 0); // here, 0 is a default value for b
}

foo("a", 2);
foo("a");

One of the limitations of this approach is that it doesn't work if you have two optional parameters of the same type and any of them can be omitted.

Varargs

a) All optional parameters are of the same type:

Copyvoid foo(String a, Integer... b) {
    Integer b1 = b.length > 0 ? b[0] : 0;
    Integer b2 = b.length > 1 ? b[1] : 0;
    //...
}

foo("a");
foo("a", 1, 2);

b) Types of optional parameters may be different:

Copyvoid foo(String a, Object... b) {
    Integer b1 = 0;
    String b2 = "";
    if (b.length > 0) {
      if (!(b[0] instanceof Integer)) { 
          throw new IllegalArgumentException("...");
      }
      b1 = (Integer)b[0];
    }
    if (b.length > 1) {
        if (!(b[1] instanceof String)) { 
            throw new IllegalArgumentException("...");
        }
        b2 = (String)b[1];
        //...
    }
    //...
}

foo("a");
foo("a", 1);
foo("a", 1, "b2");

The main drawback of this approach is that if optional parameters are of different types you lose static type checking. Furthermore, if each parameter has the different meaning you need some way to distinguish them.

Nulls

To address the limitations of the previous approaches you can allow null values and then analyze each parameter in a method body:

Copyvoid foo(String a, Integer b, Integer c) {
    b = b != null ? b : 0;
    c = c != null ? c : 0;
    //...
}

foo("a", null, 2);

Now all arguments values must be provided, but the default ones may be null.

Optional class

This approach is similar to nulls, but uses Java 8 Optional class for parameters that have a default value:

Copyvoid foo(String a, Optional<Integer> bOpt) {
    Integer b = bOpt.isPresent() ? bOpt.get() : 0;
    //...
}

foo("a", Optional.of(2));
foo("a", Optional.<Integer>absent());

Optional makes a method contract explicit for a caller, however, one may find such signature too verbose.

Update: Java 8 includes the class java.util.Optional out-of-the-box, so there is no need to use guava for this particular reason in Java 8. The method name is a bit different though.

Builder pattern

The builder pattern is used for constructors and is implemented by introducing a separate Builder class:

Copyclass Foo {
    private final String a; 
    private final Integer b;

    Foo(String a, Integer b) {
      this.a = a;
      this.b = b;
    }

    //...
}

class FooBuilder {
  private String a = ""; 
  private Integer b = 0;
  
  FooBuilder setA(String a) {
    this.a = a;
    return this;
  }

  FooBuilder setB(Integer b) {
    this.b = b;
    return this;
  }

  Foo build() {
    return new Foo(a, b);
  }
}

Foo foo = new FooBuilder().setA("a").build();

Maps

When the number of parameters is too large and for most of the default values are usually used, you can pass method arguments as a map of their names/values:

Copyvoid foo(Map<String, Object> parameters) {
    String a = ""; 
    Integer b = 0;
    if (parameters.containsKey("a")) { 
        if (!(parameters.get("a") instanceof Integer)) { 
            throw new IllegalArgumentException("...");
        }
        a = (Integer)parameters.get("a");
    }
    if (parameters.containsKey("b")) { 
        //... 
    }
    //...
}

foo(ImmutableMap.<String, Object>of(
    "a", "a",
    "b", 2, 
    "d", "value")); 

In Java 9, this approach became easier:

Copy@SuppressWarnings("unchecked")
static <T> T getParm(Map<String, Object> map, String key, T defaultValue) {
  return (map.containsKey(key)) ? (T) map.get(key) : defaultValue;
}

void foo(Map<String, Object> parameters) {
  String a = getParm(parameters, "a", "");
  int b = getParm(parameters, "b", 0);
  // d = ...
}

foo(Map.of("a","a",  "b",2,  "d","value"));

Please note that you can combine any of these approaches to achieve a desirable result.

2 of 16
595

varargs could do that (in a way). Other than that, all variables in the declaration of the method must be supplied. If you want a variable to be optional, you can overload the method using a signature which doesn't require the parameter.

Copyprivate boolean defaultOptionalFlagValue = true;

public void doSomething(boolean optionalFlag) {
    ...
}

public void doSomething() {
    doSomething(defaultOptionalFlagValue);
}
🌐
Tom Gregory
tomgregory.com › java-optional
Optional in Java: Everything You Need To Know | Tom Gregory
July 17, 2022 - At this point hopefully you've got a grasp of what Optional is all about. There are in total 17 methods you can call on the Optional class, and so far we've covered 6 of them: of, empty, ifPresent, ifPresentOrElse, orElse, and orElseThrow.
Find elsewhere
🌐
Java Code Geeks
examples.javacodegeeks.com › home › java development › core java
Java Optional Parameters - Java Code Geeks
August 11, 2021 - 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 strategy of allowing callers to supply null values.
🌐
Reddit
reddit.com › r/javahelp › how do i make parameters optional?
r/javahelp on Reddit: How do I make parameters optional?
August 31, 2023 -

I'm writing a class for a drill. My main constructor has 4 parameters, but I want the last one to be optional, such that it's not a syntax error if only do three arguments when I create an object in the test class. Here's the method:

    private int height;
private int width;
private int depth;
private String builder = null;
    
    public Box(int wide, int high, int deep, String builtBy)
{
    width = wide;
    height = high;
    depth = deep;
    builder = builtBy;
}

I want "builder" to return null for if I don't reassign it in the object creation. I thought this would happen automatically, but it says "Expected 4 arguments and found 3".

How do I do this?

EDIT: The solution is to create a second constructor with only three parameters

🌐
Baeldung
baeldung.com › home › java › core java › java default parameters using method overloading
Java Default Parameters Using Method Overloading | Baeldung
January 8, 2024 - Here, we say simulate because unlike certain other OOP languages (like C++ and Scala), the Java specification doesn’t support assigning a default value to a method parameter.
🌐
Codedamn
codedamn.com › news › java
What are optional parameters in Java?
November 19, 2023 - Parameters in Java can be broadly categorized into two types: required and optional. Required parameters are those that a method needs to function correctly. Without these parameters, the method either fails to compile or throws a runtime error. On the other hand, optional parameters are those that are not mandatory for a method’s operation.
🌐
GoLinuxCloud
golinuxcloud.com › home › java › crafting perfect code with java optional parameters
Crafting Perfect Code with Java Optional Parameters | GoLinuxCloud
October 7, 2023 - Method overloading in Java allows developers to define multiple methods with the same name but with a different number of arguments or argument types. By using method overloading, developers can create several variations of a method, each accepting a different set of parameters. This way, when the method is called with certain parameters, the appropriate version of the method is executed, effectively making some parameters optional.
🌐
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.
🌐
JetBrains
jetbrains.com › help › inspectopedia › OptionalUsedAsFieldOrParameterType.html
'Optional' used as field or parameter type | Inspectopedia Documentation
March 31, 2026 - Using a field with the java.util.Optional type is also problematic if the class needs to be Serializable, as java.util.Optional is not serializable. ... class MyClass { Optional<String> name; // Optional field // Optional parameter void setName(Optional<String> name) { this.name = name; } }
🌐
Sentry
sentry.io › sentry answers › java › does java support default parameter values?
Does Java support default parameter values? | Sentry
A default parameter value specifies the default value to be used for a method parameter when none is supplied by the caller. Although many programming languages, like Python and C++, directly support default parameter values, Java does not. However, you can achieve similar functionality in Java through method overloading, optional parameters, or the Builder pattern.
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 › javarevisited › how-to-use-default-parameters-in-java-methods-8cf8314c365c
How to Use Default Parameters in Java Methods | by omgzui | Javarevisited | Medium
January 2, 2024 - Back to the topic, I think it is a wrong choice for java to discard this syntactic sugar. The default value brings us a lot of convenience. Fortunately, we can make up for it in two ways. public void foo(String a, Integer b) { } public void foo(String a) { foo(a, 0); } foo("a", 2); foo("a"); One of the limitations of this approach is that it doesn’t work if you have two optional parameters of the same type and any of them can be omitted.
🌐
Oracle
docs.oracle.com › en › java › javase › 21 › docs › api › java.base › java › util › Optional.html
Optional (Java SE 21 & JDK 21)
January 20, 2026 - 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.
🌐
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.