This article is participating in the Java Theme Month – Java Debug Notes Event, see the event link for details
The problem
How to use optional arguments in Java? Is there any specification for optional parameters?
answer
Answer 1
To some extent, varargs (parameters of variable length) can do this. In addition, you must provide all the variables in the method declaration. If you want the variable to be optional, you can override the method, which takes no arguments.
private boolean defaultOptionalFlagValue = true;
public void doSomething(boolean optionalFlag) {... }public void doSomething(a) {
doSomething(defaultOptionalFlagValue);
}
Copy the code
Answer 2
Optional parameters in Java can be simulated in several ways:
- Method overloading
void foo(String a, Integer b) {
/ /...
}
void foo(String a) {
foo(a, 0); // the default value of b is 0
}
foo("a".2);
foo("a");
Copy the code
The limitation of this method is that it will fail if there are two optional arguments of the same type, and either of them can be ignored.
- Parameter with variable length
- 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);
Copy the code
- Optional parameter types may vary;
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");
Copy the code
Disadvantages of this method: Static type checking will not work if the optional parameter types are different. In addition, if each parameter has a different meaning, there are other ways to distinguish them.
- A null value
To address the limitations of the above methods, you can use null values and then proceed to analyze each parameter in the method body;
void foo(String a, Integer b, Integer c) { b = b ! =null ? b : 0; c = c ! =null ? c : 0;
/ /...
}
foo("a".null.2);
Copy the code
All parameter values must be supplied, but their default values can be null.
- Optional class
This method is similar to the null method, but Java 8 allows optional classes as parameter defaults;
void foo(String a, Optional<Integer> bOpt) {
Integer b = bOpt.isPresent() ? bOpt.get() : 0;
/ /...
}
foo("a", Optional.of(2));
foo("a", Optional.<Integer>absent());
Copy the code
- Constructor pattern
This is achieved by using a constructor and 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(a) {
return new Foo(a, b);
}
}
Foo foo = new FooBuilder().setA("a").build();
Copy the code
- Maps
Method parameters can be passed as their name/worth mappings when there are too many parameters and most of the default values are usually used;
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"));
Copy the code
In Java 9, this can be simplified using:
@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"));
Copy the code
These are six ways to use optional parameters, and you can combine them organically to get the results you want.
Answer 3
Since Java 1.5, optional arguments exist, and you can declare your methods as follows:
public void doSomething(boolean. optionalFlag) {
// Default is "false"
//boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false;
}
Copy the code
You can then call both doSomething() and doSomething(true).
provenance
Stack Overflow: Java Optional Parameters