What specification supports optional parameters?
17 Answers
There are several ways to simulate optional parameters in Java:
Method overloading.
void 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:
void 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:
void 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:
void 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:
void foo(String a, Optional bOpt) { Integer b = bOpt.isPresent() ? bOpt.get() : 0; //... }
foo("a", Optional.of(2)); foo("a", Optional.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:
class 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:
void 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:
@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.

- 1
- 1

- 110,878
- 29
- 149
- 111
-
8@Robino alternative link arguing that Optional should not be used as parameter [here](https://stackoverflow.com/a/39005452/2387977). Despite the use of `Optional` as parameter in one of the options, this answer is very good. – Dherik Feb 16 '18 at 14:55
-
The most common solution to the problem above is probably method overloading. Although I was never really a fan of that. Personaly I would prefer if they added some kind of identifier for configuration parameters. – Alexander Heim Dec 30 '18 at 16:31
-
3this should be probably best answer - covers all – xproph Jun 08 '19 at 15:01
-
1Voting the builders approach, which is more type-safe then Maps. When designing APIs for components that will probably be reused, putting the extra effort into appropriate Builders makes all the difference. – NicuMarasoiu Feb 15 '20 at 17:06
-
I have a class `User` with like 15 fields. Nearly 10 of them are optional and they might be null or not depending on end-user input. Compared to JS, a lot of extra code is required for creating `User` objects. What's the best solution for such classes? – Amirhosein Al Dec 22 '20 at 20:45
-
Is exists some limitations of varargs variant if optional parameter is single? As I understand, two follow calls will give same result: `someMethod("test", 1)` and `someMethod("test", 1, 2, 3)` – hohserg Jul 07 '21 at 13:18
-
@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. – Nate T Jul 18 '21 at 00:17
-
With the use of [Tiny Types](https://techbeacon.com/app-dev-testing/big-benefits-tiny-types-how-make-your-codes-domain-concepts-explicit) I find overloading has less downside as more parameters are types in themselves. – Tom Benyon Jan 02 '22 at 09:38
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.
private boolean defaultOptionalFlagValue = true;
public void doSomething(boolean optionalFlag) {
...
}
public void doSomething() {
doSomething(defaultOptionalFlagValue);
}

- 4,933
- 3
- 28
- 32

- 8,245
- 1
- 22
- 14
-
5Method overloading is a good answer in my opinion, while varargs is a very bad answer. Please either remove the comment on varargs or explain the serious disadvantage caused by the possibility of more than one return value. – Andreas Vogl Dec 26 '19 at 11:05
-
1
There is optional parameters with Java 5.0. Just declare your function like this:
public void doSomething(boolean... optionalFlag) {
//default to "false"
//boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false;
}
you could call with doSomething();
or doSomething(true);
now.
-
21This is actually the correct answer. It's simple and compact. Just remember that you could get more than one parameter so Java puts them inside an array. For example, to retrieve a single parameter you would check the contents of the array first: 'code' boolean flag = (optionalFlag.length < 1)?false:optionalFlag[0]; – Salvador Valencia Jun 26 '13 at 23:03
-
79No, it is not the correct answer, because this does not allow a single optional parameter, but any number of optional parameters. While this is close to what OP wants, it is not the same. It is a potential source of bugs and misunderstandings to accept more parameters than you need. – sleske May 28 '14 at 10:30
-
6This way works if you have just one optional parameter, but you would need to check the length of the array, etc. so it's not super clean :| If you want "one parameter" optional parameter then you may as well just declare two methods (one overloaded `doSomething() { doSomething(true); }` no arrays to deal with, no ambiguity – rogerdpack Jan 04 '17 at 21:21
-
If there are multiple optional parameters, this only works if they are all of the same data type. Well, you could make the type Object, but that's getting really ugly. – Jay Mar 29 '19 at 15:46
-
As @sleske noted, using varargs has the terrible disadvantage of allowing _more than one_ value to be passed. OP clearly asked about a solution for "optional", which means either one value or zero. How this can be consider a good answer by some is byond me. – Andreas Vogl Dec 26 '19 at 10:57
-
-
You can use something like this:
public void addError(String path, String key, Object... params) {
}
The params
variable is optional. It is treated as a nullable array of Objects.
Strangely, I couldn't find anything about this in the documentation, but it works!
This is "new" in Java 1.5 and beyond (not supported in Java 1.4 or earlier).
I see user bhoot mentioned this too below.

- 1,616
- 2
- 12
- 17
There are no optional parameters in Java. What you can do is overloading the functions and then passing default values.
void SomeMethod(int age, String name) {
//
}
// Overload
void SomeMethod(int age) {
SomeMethod(age, "John Doe");
}

- 48,658
- 8
- 97
- 130
VarArgs and overloading have been mentioned. Another option is a Bloch Builder pattern, which would look something like this:
MyObject my = new MyObjectBuilder().setParam1(value)
.setParam3(otherValue)
.setParam6(thirdValue)
.build();
Although that pattern would be most appropriate for when you need optional parameters in a constructor.

- 3,835
- 5
- 27
- 43

- 90,445
- 31
- 189
- 263
-
i want to add parameter dependency for that.let's say i want set param3 only if i set param1. For eg. i want to set progress message only if i set progress visible. isProgressVisible().setProgressMessage("loading") . how can i achieve that ? – Harshal Bhatt Jun 27 '16 at 09:56
-
@HarshalBhatt I know this is 6 years late, but for anyone else. You can enforce it at runtime with checks in the build method. You could also create a builder class with more limited interface returned from your setProgressVisible method. But a lot hinges on exactly how you want your build semantics to be. – David Bradley Apr 06 '22 at 15:14
In JDK>1.5 you can use it like this;
public class NewClass1 {
public static void main(String[] args) {
try {
someMethod(18); // Age : 18
someMethod(18, "John Doe"); // Age & Name : 18 & John Doe
} catch (Exception e) {
e.printStackTrace();
}
}
static void someMethod(int age, String... names) {
if (names.length > 0) {
if (names[0] != null) {
System.out.println("Age & Name : " + age + " & " + names[0]);
}
} else {
System.out.println("Age : " + age);
}
}
}

- 3,571
- 31
- 31
-
This is correct, `if () {} else {}` are bad for code maintenance. Method overloading is in my view the correct answer. – Gwang-Jin Kim Oct 24 '21 at 09:07
You can do thing using method overloading like this.
public void load(String name){ }
public void load(String name,int age){}
Also you can use @Nullable annotation
public void load(@Nullable String name,int age){}
simply pass null as first parameter.
If you are passing same type variable you can use this
public void load(String name...){}

- 2,758
- 1
- 31
- 38
Short version :
Using three dots:
public void foo(Object... x) {
String first = x.length > 0 ? (String)x[0] : "Hello";
int duration = x.length > 1 ? Integer.parseInt((String) x[1]) : 888;
}
foo("Hii", );
foo("Hii", 146);
(based on @VitaliiFedorenko's answer)

- 53,146
- 19
- 236
- 237
Overloading is fine, but if there's a lot of variables that needs default value, you will end up with :
public void methodA(A arg1) { }
public void methodA(B arg2) { }
public void methodA(C arg3) { }
public void methodA(A arg1, B arg2) { }
public void methodA(A arg1, C arg3) { }
public void methodA(B arg2, C arg3) { }
public void methodA(A arg1, B arg2, C arg3) { }
So I would suggest use the Variable Argument provided by Java.

- 385
- 7
- 18

- 69
- 1
- 2
-
1use of varargs is considered bad practice. if the system needs such (above mentioned) methods, then you should think of a new design as the class design looks bad. – Diablo Dec 08 '17 at 08:58
-
5It's even worse practice to make up excuses for Java deficiencies, and accuse others of bad practice for noticing those inconveniences and devising workarounds. – BrianO Mar 19 '18 at 20:35
-
2Please add all relevant information to your answer instead of linking to external sources - the given link is dead – Nico Haase Oct 30 '19 at 08:50
-
Code like that is a code smell and should be refactored anyway--use Introduce Parameter Object or convert to FunctionalInterface and use Builder Pattern. – awgtek Jul 29 '21 at 17:30
You can use a class that works much like a builder to contain your optional values like this.
public class Options {
private String someString = "default value";
private int someInt= 0;
public Options setSomeString(String someString) {
this.someString = someString;
return this;
}
public Options setSomeInt(int someInt) {
this.someInt = someInt;
return this;
}
}
public static void foo(Consumer<Options> consumer) {
Options options = new Options();
consumer.accept(options);
System.out.println("someString = " + options.someString + ", someInt = " + options.someInt);
}
Use like
foo(o -> o.setSomeString("something").setSomeInt(5));
Output is
someString = something, someInt = 5
To skip all the optional values you'd have to call it like foo(o -> {});
or if you prefer, you can create a second foo()
method that doesn't take the optional parameters.
Using this approach, you can specify optional values in any order without any ambiguity. You can also have parameters of different classes unlike with varargs. This approach would be even better if you can use annotations and code generation to create the Options class.

- 53
- 4
If it's an API endpoint, an elegant way is to use "Spring" annotations:
@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam(required = false, defaultValue = "hello") String id) {
return innerFunc(id);
}
Notice in this case that the innerFunc will require the variable, and since it's not api endpoint, can't use this Spring annotation to make it optional. Reference: https://www.baeldung.com/spring-request-param

- 434
- 4
- 9
Java now supports optionals in 1.8, I'm stuck with programming on android so I'm using nulls until I can refactor the code to use optional types.
Object canBeNull() {
if (blah) {
return new Object();
} else {
return null;
}
}
Object optionalObject = canBeNull();
if (optionalObject != null) {
// new object returned
} else {
// no new object returned
}

- 2,254
- 1
- 28
- 20
This is an old question maybe even before actual Optional type was introduced but these days you can consider few things: - use method overloading - use Optional type which has advantage of avoiding passing NULLs around Optional type was introduced in Java 8 before it was usually used from third party lib such as Google's Guava. Using optional as parameters / arguments can be consider as over-usage as the main purpose was to use it as a return time.
Ref: https://itcodehub.blogspot.com/2019/06/using-optional-type-in-java.html

- 1,171
- 11
- 7
Default arguments can not be used in Java. Where in C#, C++ and Python, we can use them..
In Java, we must have to use 2 methods (functions) instead of one with default parameters.
Example:
Stash(int size);
Stash(int size, int initQuantity);

- 1,844
- 1
- 23
- 34

- 123
- 1
- 2
We can make optional parameter by Method overloading or Using DataType...
|*| Method overloading :
RetDataType NameFnc(int NamePsgVar)
{
// |* Code Todo *|
return RetVar;
}
RetDataType NameFnc(String NamePsgVar)
{
// |* Code Todo *|
return RetVar;
}
RetDataType NameFnc(int NamePsgVar1, String NamePsgVar2)
{
// |* Code Todo *|
return RetVar;
}
Easiest way is
|*| DataType... can be optional parameter
RetDataType NameFnc(int NamePsgVar, String... stringOpnPsgVar)
{
if(stringOpnPsgVar.length == 0) stringOpnPsgVar = DefaultValue;
// |* Code Todo *|
return RetVar;
}

- 4,974
- 11
- 52
- 88
-
11
-
Can you add some more explanation to that code? What do all these strange variables do? – Nico Haase Oct 30 '19 at 08:50
If you are planning to use an interface with multiple parameters, one can use the following structural pattern and implement or override apply - a method based on your requirement.
public abstract class Invoker<T> {
public T apply() {
return apply(null);
}
public abstract T apply(Object... params);
}

- 3,284
- 23
- 36