views:

5905

answers:

8

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?

+7  A: 

Sadly, no.

Rob H
Is it so sad? Doing so would introduce potentially ambiguous function signatures.
Trey
I agree with Trey. This isn't sad :) and since default parameters exists since a long time, I guess Java engineers have some good reasons to don't include it ;)
AkiRoss
+16  A: 

No, the structure you found is how Java handles it (i.e. with overloading instead of default parameters).

For constructors See Effective Java'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.

Kathy Van Stone
+1  A: 

NO.You can achieve the same behavior by passing an Object which has smart defaults.But again it depends what your case at hand.

+3  A: 

No. In general Java doesn't have much (any) syntactic sugar, since they tried to make a simple language.

tomjen
+15  A: 

No, but you can use the Builder Pattern, as described in this Stack Overflow answer.

As described in the linked answer, the Builder Pattern lets you write code like

Student s1 = new StudentBuilder().name("Eli").buildStudent();
Student s2 = new StudentBuilder()
                 .name("Spicoli")
                 .age(16)
                 .motto("Aloha, Mr Hand")
                 .buildStudent();

in which some fields can have default values or otherwise be optional.

Eli Courtwright
A: 

There are half a dozen or better issues such as this, eventually you arrive at the static factory pattern ... see the crypto api for that. Sort difficult to explain, but think of it this way: If you have a constructor, default or otherwise, the only way to propagate state beyond the curly braces is either to have a Boolean isValid; ( along with the null as default value v failed constructor ) or throw an exception which is never informative when getting it back from field users.

Code Correct be damned, I write thousand line constructors and do what I need. I find using isValid at object construction - in other words, two line constructors - but for some reason I am migrating to the static factory pattern. I just seems you can do a lot if you in a method call, there are still sync() issues but defaults can be 'substituted' better ( safer )

I think what we need to do here is address the issue of null as default value vis-a-vis something String one=new String(""); as a member variable, then doing a check for null before assigning string passed to the constructor.

Very remarkable the amount of raw, stratospheric computer science done in Java.

C++ and so on has vendor libs, yes. Java can outrun them on large scale servers due to it's massive toolbox. Study static initializer blocks, stay with us.

Nicholas Jordan
+2  A: 

Unfortunately, yes.

void MyParameterizedFunction(String param1, int param2, bool param3=false) {}

could be written in java 1.5 as:

void MyParameterizedFunction(String param1, int param2, Boolean... params) {
    assert params.length <= 1;
    bool param3 = params.length > 0 ? params[0].booleanValue() : false;
}

But whether or not you should depends on how you feel about the compiler generating a

new Boolean[]{}

for each call.

[edit]
For multiple defaultable parameters:

void MyParameterizedFunction(String param1, int param2, Object... p) {
    int l = p.length;
    assert l <= 2;
    assert l < 1 || Boolean.class.isInstance(p[0]);
    assert l < 2 || Integer.class.isInstance(p[1]);
    bool param3 = l > 0 && p[0] != null ? ((Boolean)p[0]).booleanValue() : false;
    int param4 = l > 1 && p[1] != null ? ((Integer)p[1]).intValue();
}

This matches C++ syntax, which only allows defaulted parameters at the end of the parameter List.

Beyond syntax, there is a difference where this has run time type checking for passed defaultable parameters and C++ type checks them during compile.

ebelisle
Clever, but varargs (...) can only be used for the final parameter, which is more limiting than what languages supporting default parameters give you.
CurtainDog
I've added an example for multiple defaultable parameters.
ebelisle
A: 

yes,java support default values

Shri ram sharma