21

I've been looking around to try to find what the reasoning is behind not including default parameters for functions in Java.

I'm aware that it's possible to simulate the behavior, either with varargs or else by creating several overloaded functions that accept fewer parameters, and call the real function that takes all parameters. However, neither of these options match the clarity and ease-of-use of, e.g. C++'s syntax.

Does anyone know if there's a solid technical reason that would make something like

void myFunc(int a=1, int b=2) {...}

undesirable or undo-able in a new version of Java?

Singleton
  • 3,701
  • 3
  • 24
  • 37
Kricket
  • 4,049
  • 8
  • 33
  • 46

4 Answers4

5

It was not in the initial version of Java because they decided they did not need it, probably to keep things simple.

Adding it now would be tricky, because it needs to be done in a backwards-compatible fashion. Adding varargs, autoboxing and generics in Java5 was a major undertaking, and it could only be done with limited functionality (such as type erasure) and at the cost of increased complexity (the new method resolution rules make for good exam trick questions).

Your best shot would be with a non-Java language on the JVM. Maybe one of them already has this.

Thilo
  • 257,207
  • 101
  • 511
  • 656
3

I am not aware of a technical reason, apart from it being complicated which values are being omitted and which ones are not.

For example, in your sample, if only one integer was passed through then is it a or b that should be defaulted? Most probably a but it does add that level of ambiguity.

A simple solution would be to

void myFunc(Integer a, Integer b) {
  if (a == null) a = 1;
  if (b == null) b = 2;

}

Yes it is more long winded, and yes it hides the defaulting within the code, rather than the method signature (which could then be shown in JavaDoc), but it does enforce the consistency.

mytest
  • 198
  • 6
  • 15
    I disagree. In C++ there's no ambiguity - although it comes at the price of being slightly limited in which parameters you can specify (i.e. you can't let the first one be default and give a value for the second). However, this is a minor problem when you have an IDE like Eclipse that will tell you what the method's signature is. FlexBuilder does this quite well... – Kricket Nov 26 '10 at 09:38
  • In addition to Kelsey's point, an advantage of default parameter is to make method call more concise. Your solution for default value does not have this advantage. – Nicolas Nov 26 '10 at 10:03
1

I agree that optional arguments would add huge clarity and save the huge work of defining loads of overloaded methods (called telescoping), which do nothing than call each other. However, the enabler for this neat feature is passing arguments by name.

Named association is self-documenting. In contrast, positional argument association is concise but it makes you to refer the definition of method all the time to check which argument is expected in nth position at every invocation. This is ridiculous and motivates us to search for solutions like Builder pattern. The Builder actually solves both problems at once because named association is a synonym for optional arguments. But Builder is useful only for user. API designer still must waste space/time to create the Builder class. Pattern bigots might disagree but it is an overkill to create a Builder class for every method with named/optional arguments. Language design should obviate this stupid pattern. But, I do not know how compatible they are with the variable argument list.

Community
  • 1
  • 1
Val
  • 1
  • 8
  • 40
  • 64
  • Sure, there are work-arounds, but what I'm looking for is why the language designers chose to omit this useful and simple-seeming functionality. – Kricket Oct 24 '13 at 09:37
  • It could be a pure omission for no reason. Sometimes you just have more priority tasks and leave out some less important things. The fact that they did not make any effort to implement a feature, argues for that. Compare this with the irritation that `super` must be the first statement in the constructor. Here they undertaken serious effort to prevent neat coding. That is what infuriates me and begs for the serious question since normal people don't spend efforts to do harm. – Val Oct 24 '13 at 09:50
  • OK, but you're speculating - do you have a source to back up your claim? – Kricket Oct 24 '13 at 12:52
0

To Avoid Ambiguity. Java Support Method Override.

We assume the code below:

public int add(int a) {
    // do something
}

public int add(int a, int b = 0) {
    // do something
}

When we call add(12), Can you tell me which function is invoked?

Max Xu
  • 2,403
  • 1
  • 15
  • 13
  • 4
    Compiler will display something like "call to 'add' is ambiguous" and thus prevent this situation – creekorful Apr 09 '18 at 14:45
  • 1
    A better question is why would you have two versions of the exact same function, one with default parameter? Logically, you should only have add(int a, int b = 0) in which case calling int(12) and int(12, 0) are equals. if add(int a) and add(int a, int b = 0) are equal then why do you have two versions? – Mandemon Jan 09 '20 at 11:12
  • As mentioned by @creekorful, that is not a valid reason, as the compiler can detect such ambiguities and show an error. C++ does it and supports method override AND default parameters. – Alan Evangelista Jul 16 '21 at 09:22