I came across some Java code that had the following structure:
public MyParameterizedFunction(String param1, int param2)
{
this(param1, param2, false);
}
public MyParameterizedFunction(String param1, int param2, boolean param3)
{
//use all three parameters here
}
I know that in C++ I can assign a parameter a default value. For example:
void MyParameterizedFunction(String param1, int param2, bool param3=false);
Does Java support this kind of syntax? Are there any reasons why this two step syntax is preferable?
No, but the simplest way to implement this is:
Or instead of the ternary operator you can use if:
You may use Java Method Invocation Builder to automatically generate the builder with default values.
Just add @GenerateMethodInvocationBuilder to the class, or interface, and the @Default to parameters in methods where you want default values. A builder will be generated at compile time, using the default values that you specified with your annotations.
And then you can invoke the methods.
Or set any of the default values to something else.
NO, But we have alternative in the form of function overloading.
called when no parameter passed
called when "a" parameter was passed
called when parameter b passed
There are several ways to simulate default parameters in Java:
Method overloading.
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:
b) Types of optional parameters may be different:
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 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 analyse each parameter in a method body:
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:
Optional makes a method contract explicit for a caller, however, one may find such signature too verbose.
Builder pattern. The builder pattern is used for constructors and is implemented by introducing a separate Builder class:
Maps. When the number of parameters is too large and for most of them default values are usually used, you can pass method arguments as a map of their names/values:
Please note that you can combine any of these approaches to achieve a desirable result.
This is how I did it ... it's not as convenient perhaps as having an 'optional argument' against your defined parameter, but it gets the job done:
Notice I can invoke the same method name with either just a string or I can invoke it with a string and a boolean value. In this case, setting wipeClean to true will replace all of the text in my TextArea with the provided string. Setting wipeClean to false or leaving it out all together simply appends the provided text to the TextArea.
Also notice I am not repeating code in the two methods, I am merely adding the functionality of being able to reset the TextArea by creating a new method with the same name only with the added boolean.
I actually think this is a little cleaner than if Java provided an 'optional argument' for our parameters since we would need to then code for default values etc. In this example, I don't need to worry about any of that. Yes, I have added yet another method to my class, but it's easier to read in the long run in my humble opinion.
No, the structure you found is how Java handles it (that is, with overloading instead of default parameters).
For constructors, See Effective Java: Programming Language Guide's Item 1 tip (Consider static factory methods instead of constructors) if the overloading is getting complicated. For other methods, renaming some cases or using a parameter object can help. This is when you have enough complexity that differentiating is difficult. A definite case is where you have to differentiate using the order of parameters, not just number and type.