1826

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?

Wolf
  • 8,482
  • 7
  • 48
  • 92
gnavi
  • 21,966
  • 7
  • 19
  • 11

25 Answers25

1054

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Kathy Van Stone
  • 23,459
  • 3
  • 29
  • 40
  • 27
    this was in 2009, `static` anything is pretty much considered harmful in 2015. [Type safe fluent `Builder` instances that enforce complete and valid construction contracts are a much better solution now.](http://www.vertigrated.com/blog/2015/08/fluent-builder-pattern-revisited/) –  Dec 18 '15 at 04:27
  • 155
    @JarrodRoberson: Static factory methods are no more harmful than `new`. They are [used](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Paths.html#get-java.lang.String-java.lang.String...-) all the [time](https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#of-int-int-int-int-int-) in new code. Builders for simple value objects are often the result of over-engineering. – Lii Jan 22 '16 at 08:38
  • 13
    @JarrodRoberson: Interesting way of forcing correct use via the compiler, thanks for sharing! Friendly suggestion for future posts: 300 lines of uncommented source code is probably a bit much to digest for most people (code is harder to read than to write, after all). Thanks again! – Christian Aichinger Jan 27 '16 at 21:55
  • 1
    @ChristianAichinger - I have an even more strict advanced technique I am using now that combines generic interfaces with abstract classes with private constructors that I am working writing up as a blog post. My blog link is in my profile. *as an aside, self documenting code does not need comments :)* –  Jan 27 '16 at 22:01
  • 17
    @JarrodRoberson: Nice, looking forward to it! What I wanted to communicate: as a reader of your blog, a 50 line example with a brief text description of what's going on would help me more than 300 lines without context. – Christian Aichinger Jan 27 '16 at 22:12
  • 13
    @user177800 Disagree - static methods if written as pure functions are perfectly fine. It's when a static function mutates state that they become a problem... – Levi Fuller Dec 18 '18 at 03:47
  • 6
    @user177800 in 2020 your link is dead. – user2183336 Apr 01 '20 at 17:31
  • 2
    I wonder if (JarrodRoberson.equals(user177800))... – nephewtom Mar 08 '21 at 15:58
694

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.

Community
  • 1
  • 1
Eli Courtwright
  • 164,889
  • 61
  • 203
  • 255
  • 150
    Finally e great less-than-2-pages example of the Builder pattern. – nevvermind Nov 08 '12 at 21:38
  • 16
    Im curious though, why do we need a builder class when using the builder pattern. I was thinking of Student s1 = new Student().name("Spicolo").age(16).motto("Aloha, Mr Hand); – ivanceras Feb 14 '13 at 08:32
  • 59
    @ivanceras: It's relevant when classes have required fields, and you don't want to be able to instantiate those classes in an invalid state. So if you just said `Student s1 = new Student().age(16);` then that would leave you with a Student without a name, which might be bad. If it's not bad, then your solution is fine. – Eli Courtwright Feb 14 '13 at 18:33
  • 65
    @ivanceras: another reason is you might want your class to be immutable after construction, so you wouldn't want methods in it that change its values. – Jules Feb 27 '13 at 16:02
  • 4
    @ivanceras: I used Builders for 3 things - eliminating the multiple argument and fluent initialization, immutability and most importantly I feel to validate the domain object in the build() method.Why create an object instance if is invalid.You can also overload static factory methods like in the above case buildFreshman(), buildSenior() etc – Abhijeet Kushe Aug 16 '15 at 22:00
  • this is exactly what default arguments are all about! amazing! you can also use the BFATV (be fully and totally verbose pattern) – perreal Apr 18 '17 at 05:24
  • The use of the Builder pattern here seems rather superfluous for what the OP is asking (default parameter values.) As a matter of fact, I don't see how this provides an answer to the original question at all. – luis.espinal Jan 03 '19 at 17:02
  • Downvote all you want, this doesn't answer or address the original question. – luis.espinal Jan 03 '19 at 22:02
  • That's the telescoping constructor. The Builder Pattern of the GoF is somewhat different. – DPM Jan 21 '20 at 14:01
536

There are several ways to simulate default parameters in Java:

  1. 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.

  2. 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 different meaning you need some way to distinguish them.

  3. Nulls. To address the limitations of the previous approaches you can allow null values and then analyse 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.

  4. 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<Integer> bOpt) {
        Integer b = bOpt.isPresent() ? bOpt.get() : 0;
        //...
    }
    
    foo("a", Optional.of(2));
    foo("a", Optional.<Integer>absent());
    

    Optional makes a method contract explicit for a caller, however, one may find such signature too verbose.

  5. 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();
    
  6. 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:

    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 = (String)parameters.get("a");
        } else if (parameters.containsKey("b")) { 
            //... 
        }
        //...
    }
    
    foo(ImmutableMap.<String, Object>of(
        "a", "a",
        "b", 2, 
        "d", "value")); 
    

Please note that you can combine any of these approaches to achieve a desirable result.

Vitalii Fedorenko
  • 97,155
  • 26
  • 144
  • 111
  • 1
    Good explanation. I've never seen return values used like this. For 5) what do the `return this` do? Also, doesn't `FooBuilder().setA("a").build();` since (by definition) the constructor is called first and `FooBuilder()` returns a value, doesn't this mean `.setA("a"):` doesn't get the chance to be called? – Celeritas Jul 18 '14 at 22:37
  • 6
    @Celeritas `return this` returns the same object on which the method was called (in the example, `FooBuilder`). This allows chaining of methods in one statement acting on the same object: `new FooBuilder().setA(..).setB(..).setC(..)` etc as opposed to calling each method in a separate statement. – ADTC Aug 27 '14 at 08:44
  • 3
    @Celeritas `new FooBuilder()` returns a `FooBuilder` object on which the `setA` method is called. As `setB` is not called, `this.b` retains the default value. Finally the `build` method is called on this `FooBuilder` object. The `build` method creates and returns a `Foo` object which is set to the variable `Foo foo`. Notice that the `FooBuilder` object is not stored in any variable. – ADTC Aug 27 '14 at 08:48
  • Annotation can also be used to create default parameters and is most useful when required for polymorphic collections. http://docs.oracle.com/javase/tutorial/java/annotations/declaring.html – Martin Spamer Jan 27 '15 at 09:47
  • 1
    Over 900 upvotes on the same answer across two questions. I'm impressed: http://stackoverflow.com/questions/965690/java-optional-parameters/12994104#12994104 – AdamMc331 Nov 28 '15 at 19:19
  • Java now supports optionals in 1.8, no need for guava :) – Pellet Sep 01 '16 at 02:57
  • Thanks for the answer. It sad to see so many methods with not even one approaching C# in usability. – Kolya Ivankov Oct 17 '17 at 09:26
  • In case **6**, why didn't use `else if`, instead of just multiple `if`?! – Dr.jacky Jun 14 '18 at 17:33
286

Sadly, no.

Rob H
  • 12,976
  • 8
  • 38
  • 44
  • 35
    Is it so sad? Doing so would introduce potentially ambiguous function signatures. – Trey Jun 15 '09 at 19:46
  • 1
    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 Jan 21 '10 at 11:42
  • 70
    @Trey: languages with default parameters often ditch function overloading since it is then less compelling. So no ambiguity. Beside, Scala added the feature in 2.8, and somehow solved the ambiguity issue (since they kept the overloading for compatibility reasons). – PhiLho May 24 '11 at 13:09
  • @PhiLho Yup, I love Scala but I don't mind lack of the feature in Java. It's really not that big of a deal that it is missing IMO. Scala allows them most of the time but will, in some circumstances at compile time, produce AmbiguousSignature errors (or something like that). – Trey Jun 04 '11 at 04:45
  • 12
    @Trey: read up how Ada implements overloading and default parameters and how Ada avoids ambiguity with named parameters. It take time to get the design right. Time the Java Team did not have. — PhiLho: Like Ada Scala has named parameter. A simple way to solve the problem. And they make the code better to read on top. – Martin Sep 18 '11 at 12:53
  • 2
    I believe parameter defaults are bad practice and overloading is a much cleaner solution. You can even hide the default constructor and use static factory methods to return initialized instances. This is also useful for IOC, where you determine the implementation of the interface to return. If you want to optionally assign a property, create a public property, or overload a constructor Having another way to perform the same function does not make it better. It just makes the language more cryptic and is simply lazy programming when this *is* one of the reasons for function overloading. – Antony Booth Nov 14 '13 at 18:58
  • 35
    I fail to see how parameter defaults prevent function overloading. C# for instance allows overrides and also allows for default initializes. Seems like arbitrary choice, not restriction is the reason. – FlavorScape Nov 30 '13 at 17:43
  • 58
    Yeah, lets trade off making the compiler do some extra work and instead make us all write 100000 overloads to give our library users convenience. Good idea. –  May 13 '14 at 08:02
  • 1
    I agree that it's sad. When I'm writing a Java API for people to call from JRuby, I end up having to make every method take `Map,?>` and cram all parameters into the map so that idiomatic Ruby can be written. I'd much prefer parameter names and defaults because the Javadoc would look a lot nicer. – Trejkaz Nov 18 '14 at 22:05
  • 3
    Works in C# for many years now without problems, even combined with method overloading. Compiler shows a warning on conflicts and that's it. Just do something like writeToFile(String content, boolea append=false); – spyro Oct 13 '16 at 15:21
  • 32
    @user562566: Whenever I work on a Java project, I get the impression that Java devs are paid/measured by how many lines of code they produce per day – Mark K Cowan Oct 16 '16 at 20:38
  • 1
    @MarkKCowan Do auto generated _getters/setters_ "count" ? – StephenBoesch Feb 15 '19 at 04:40
  • 1
    @javadba any lines in the source file, to a stupid enough manager. That's why java would be awesome in such companies, you'd get paid 3x more than the C# guy for writing the exact same program! – Mark K Cowan Feb 15 '19 at 09:31
  • 1
    Yes, sad, indeed. No problem in almost other languages (C#, Kotlin, Scala, Groovy, Typescript, Javascript....) – spyro Nov 18 '19 at 12:20
86

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 depend on how you feel about the compiler generating a

new Boolean[]{}

for each call.

For multiple defaultable parameters:

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

could be written in Java 1.5 as:

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() : 42;
}

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
  • 1,107
  • 7
  • 9
  • 16
    Clever, but varargs (...) can only be used for the final parameter, which is more limiting than what languages supporting default parameters give you. – CurtainDog May 26 '10 at 22:20
  • 2
    I've added an example for multiple defaultable parameters. – ebelisle May 27 '10 at 02:52
  • 6
    that's clever but a bit messy compared to the C++ version – Someone Somewhere Nov 04 '11 at 18:27
  • 5
    Java definitely needs optional defaulted parameters as C# and others allow... the syntax is obvious and I presume they can implement this fairly simply even by just compiling all possible combinations... I cannot imagine why they haven't added it to the language yet! – jwl Feb 23 '12 at 23:31
  • 10
    One should never use an `assert` in production code. Throw an exception. – Michael Dorst Oct 01 '13 at 18:52
  • @joelarson maybe they're just trying to keep extra syntaxes to a minimum. – Michael Dorst Oct 01 '13 at 18:56
  • `Boolean` != `boolean`... `Boolean.class.isInstance(p[0]);` can be written as `p[0] instanceof Boolean`... – Clashsoft Feb 21 '15 at 18:36
  • 5
    -1 This really isn't what varargs is for. This is a hack. -- in this case, using overloads will be way more readable (which is unfortunate, since three extra characters is more readable than 5 extra lines of source...). -- but Java does not support default parameters. – BrainSlugs83 Apr 18 '15 at 18:43
  • That is so messy and error prone. I don't see any, any reason to use this instead of original way in the question (which author tried to simplify even further). – volkovs Apr 21 '16 at 15:06
42

No, but you can very easily emulate them. What in C++ was:

public: void myFunction(int a, int b=5, string c="test") { ... }

In Java, it will be an overloaded function:

public void myFunction(int a, int b, string c) { ... }

public void myFunction(int a, int b) {
    myFunction(a, b, "test");
}

public void myFunction(int a) {
    myFunction(a, 5);
}

Earlier was mentioned, that default parameters caused ambiguous cases in function overloading. That is simply not true, we can see in the case of the C++: yes, maybe it can create ambiguous cases, but these problem can be easily handled. It simply wasn't developed in Java, probably because the creators wanted a much simpler language as C++ was - if they had right, is another question. But most of us don't think he uses Java because of its simplicity.

peterh
  • 9,698
  • 15
  • 68
  • 87
  • 9
    The main idea of C# default value notation is precisely to avoid this boilerplate coding and have just one constructor instead of many. – Kolya Ivankov Oct 17 '17 at 09:27
  • 1
    @KolyaIvankov I don't know C#, but I know C++ where the reasoning is the same. I don't know what is the better, but I think, actually the same boilerplate code is generated by the compiler in the case of C++/C# and it is going into the final binary. – peterh Oct 17 '17 at 09:34
  • 7
    Every programming language is (in particular) a means to avoid an Assembler boilerplate, am I wrong? The question is only whether it gives a handy functionality, or not. – Kolya Ivankov Oct 17 '17 at 11:45
  • @KolyaIvankov I don't really understand your question. If you have a question, ask this as a question. – peterh Oct 17 '17 at 12:47
  • 2
    First sentence is a rhetorical question. The word "question" in the second sentence has nothing to do with the rhetorical question in the first. – Kolya Ivankov Oct 17 '17 at 13:44
  • 1
    Being more specific: languages are tools that allow us to write programs in a way we can have control over what is written, compiling is a way to tell a machine what we want from it. A tool is more useful if it allows us to avoid boilerplate. In effect, gnavi asked, if they can avoid precisely the type of boilerplate code you propose as an answer, since C# allows for it. – Kolya Ivankov Oct 17 '17 at 13:50
  • thank you for edit. – jezrael Jan 27 '21 at 14:24
  • @peterh-ReinstateMonica - Interesting ;) – jezrael Jan 27 '21 at 14:32
27

You can do this is in Scala, which runs on the JVM and is compatible with Java programs. http://www.scala-lang.org/

i.e.

class Foo(var prime: Boolean = false, val rib: String)  {}
om-nom-nom
  • 60,231
  • 11
  • 174
  • 223
lythic
  • 472
  • 4
  • 7
  • 61
    Bring whole new language to get one not so common feature? – om-nom-nom Apr 03 '12 at 13:59
  • 8
    @om-nom-nom: Java should never existed. Saying that a feature is not used is equivalent that nobody needs it is saying that Java was not popular before it was invented means that Gosling should not start designing it. – Val Jun 15 '12 at 15:17
  • 28
    @Val just saying that this is like shooting birds with cannons – om-nom-nom Jun 15 '12 at 15:22
  • 8
    that has nothing to do with the OP's question – destan Nov 07 '16 at 15:45
  • 2
    Works in Kotlin, too. And Groovy. And C#. And Javascript. And almost all other languages which are made for real people and problems. – spyro Apr 29 '20 at 15:42
19

No, but the simplest way to implement this is:

public myParameterizedFunction(String param1, int param2, Boolean param3) {

    param3 = param3 == null ? false : param3;
}

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

or instead of the ternary operator, you can use if:

public myParameterizedFunction(String param1, int param2, Boolean param3) {

    if (param3 == null) {
        param3 = false;
    }
}

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}
simhumileco
  • 21,911
  • 14
  • 106
  • 90
  • 2
    Yes, this approach seems to be the best from the other alternatives. Still it would be nice for Java to adopt default values; Kotlin showed that this can be done, so I am not sure why Oracle does not enter the modern era, and keeps on designing java as if it were the 1990s. :D – shevy Mar 03 '20 at 14:54
16

I might be stating the obvious here but why not simply implement the "default" parameter yourself?

public class Foo() {
        public void func(String s){
                func(s, true);
        }
        public void func(String s, boolean b){
                //your code here
        }
}

for the default, you would either use

func("my string");

and if you wouldn't like to use the default, you would use

func("my string", false);
OmG
  • 15,398
  • 7
  • 42
  • 71
IronWolf
  • 179
  • 1
  • 5
  • 15
    The poster asked if this (rather ugly) pattern can be avoided ... ;-) In more modern languages (like c#, Scala) you don't need this extra overloads which only creates more lines of code. Up to some point you can use varargs in the meantime (static int max( int... array ) { }), but they are only a very ugly workaround. – Offler Feb 18 '13 at 14:10
  • 2
    Overloading is not ugly and has many benefits, such as different method calls with different signatures can perform different functionality. `//This is better public class Foo() { /* This does something */ public void func(String s){ //do something } /* This does something else with b */ public void func(String s, boolean b){ // b was passed } }` `//Than this public class Foo() { /* This does something unless b = value, then it does something else */ public void func(String s, boolean b = value){ If (b){ // Do Something } else{ // Do something else } } }` – Antony Booth Nov 14 '13 at 19:57
  • 1
    Well, if one wants differing behaviour. If the only difference is a slight change in calculations, etc., it is sure a waste of effort to create multiple signatures. Defaults make sense where you need them to... and lack of it shouldn't be classified as a "useless" requirement. – Kapil Jan 20 '14 at 04:47
  • @Offler default parameters have nothing to do with "modern language". I used them in Delphi 20 years ago and they probably already existed in Turbo Pascal. – The incredible Jan Apr 06 '17 at 13:09
  • 1
    I agree with Offler, and disagree with Antony Booth. I find it not only ugly but also fairly inefficient. Languages such as ruby or python make it trivial to use default parameters; I guess what Java requires you to do is to find (and use) workarounds. The explicit check versus null seems to be the least ugly choice, since I may call that from the commandline too (just not provide anything, and then handle the sane variant); the operator overloading approach seems ... very verbose (like at least +3 lines, compared to the null-check, and more lines if the code is more complex). – shevy Mar 03 '20 at 14:53
14

Instead of using:

void parameterizedMethod(String param1, int param2) {
    this(param1, param2, false);
}

void parameterizedMethod(String param1, int param2, boolean param3) {
    //use all three parameters here
}

You could utilize java's Optional functionality by having a single method:

void parameterizedMethod(String param1, int param2, @Nullable Boolean param3) {
    param3 = Optional.ofNullable(param3).orElse(false);
    //use all three parameters here
}

The main difference is that you have to use wrapper classes instead of primitive Java types to allow null input.Boolean instead of boolean, Integer instead of int and so on.

8

As Scala was mentioned, Kotlin is also worth mentioning. In Kotlin function parameters can have default values as well and they can even refer to other parameters:

fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) {
    ...
}

Like Scala, Kotlin runs on the JVM and can be easily integrated into existing Java projects.

mrts
  • 11,067
  • 5
  • 65
  • 58
6

No.

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

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Santosh Gokak
  • 3,193
  • 3
  • 19
  • 23
6

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

tomjen
  • 3,595
  • 3
  • 24
  • 35
  • 28
    Not quite. The bitter truth is that the team was on a tight schedule and had no time for syntactic sugar. Why else would `const` and `goto` be reserved keywords which no implementation? — Especially `const` is something I miss bitterly — `final` is no replacement and they knew it. — And if you made the *concious* decision to never implement `goto` you won't need to reserve the keyword. — And later in the Java Team cheated by making the Label based `break` and `continue` as powerful as a Pascal `goto`. – Martin Sep 18 '11 at 12:46
  • "Simple, Object-Oriented and Familiar" was indeed a design goal - see http://www.oracle.com/technetwork/java/intro-141325.html – mikera Sep 02 '13 at 09:27
  • 1
    tomjen said: "No. In general Java doesn't have much (any) syntactic sugar, since they tried to make a simple language". So you are saying that removing a lot of unnecessary features from C++ makes a Java a simple language, then tell me why Java does have variadic methods? Why does it have varargs? It is not needed if you can simply use an array of objects instead, am I right? So varargs can be removed from the language, because it is unnecessary. This will make Java more simple than what it is now. Am I right? Overloading also can be removed, because you have infinite names for each method. –  Aug 08 '17 at 15:58
  • 1
    and that's why we got spring and stuff that take the simple language and turn any real Java project into a clusterfuck of syntax and boilerplate :-) – matanster Aug 17 '19 at 08:54
  • 1
    Forcing devs to boilerplate code and complicated workarounds is not my understanding of the word "easy". myFunction(a, b=false, c = 3), that's what I call easy. – spyro Apr 29 '20 at 15:44
4

It is not supported but there are several options like using parameter object pattern with some syntax sugar:

public class Foo() {
    private static class ParameterObject {
        int param1 = 1;
        String param2 = "";
    }

    public static void main(String[] args) {
        new Foo().myMethod(new ParameterObject() {{ param1 = 10; param2 = "bar";}});
    }

    private void myMethod(ParameterObject po) {
    }
}

In this sample we construct ParameterObject with default values and override them in class instance initialization section { param1 = 10; param2 = "bar";}

hoaz
  • 9,293
  • 4
  • 38
  • 51
3

Try this solution:

public int getScore(int score, Integer... bonus)
{
    if(bonus.length > 0)
    {
        return score + bonus[0];
    }

    return score;
}
Hamzeh Soboh
  • 7,070
  • 5
  • 37
  • 54
3

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.

@GenerateMethodInvocationBuilder
public class CarService {
 public CarService() {
 }

 public String getCarsByFilter(//
   @Default("Color.BLUE") Color color, //
   @Default("new ProductionYear(2001)") ProductionYear productionYear,//
   @Default("Tomas") String owner//
 ) {
  return "Filtering... " + color + productionYear + owner;
 }
}

And then you can invoke the methods.

CarService instance = new CarService();
String carsByFilter = CarServiceGetCarsByFilterBuilder.getCarsByFilter()//
  .invoke(instance);

Or set any of the default values to something else.

CarService instance = new CarService();
String carsByFilter = CarServiceGetCarsByFilterBuilder.getCarsByFilter()//
  .withColor(Color.YELLOW)//
  .invoke(instance);
Tomas Bjerre
  • 2,594
  • 18
  • 20
3

It is not supported in java as in other language for ex. Kotlin.

2

A similar approach to https://stackoverflow.com/a/13864910/2323964 that works in Java 8 is to use an interface with default getters. This will be more whitespace verbose, but is mockable, and it's great for when you have a bunch of instances where you actually want to draw attention to the parameters.

public class Foo() {
    public interface Parameters {
        String getRequired();
        default int getOptionalInt(){ return 23; }
        default String getOptionalString(){ return "Skidoo"; }
    }

    public Foo(Parameters parameters){
        //...
    }

    public static void baz() {
        final Foo foo = new Foo(new Person() {
            @Override public String getRequired(){ return "blahblahblah"; }
            @Override public int getOptionalInt(){ return 43; }
        });
    }
}
Community
  • 1
  • 1
Novaterata
  • 3,327
  • 22
  • 39
2

I've now spent quite some time to figure out how to use this with methods that return values, and I haven't seen any examples so far, I thought it might be useful to add this here:

int foo(int a) {
    // do something with a
    return a;
}

int foo() {
    return foo(0); // here, 0 is a default value for a
}
AAGD
  • 1,237
  • 1
  • 11
  • 17
1

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 seem 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 a massive toolbox. Study static initializer blocks, stay with us.

OmG
  • 15,398
  • 7
  • 42
  • 71
Nicholas Jordan
  • 628
  • 3
  • 6
1

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:

public void postUserMessage(String s,boolean wipeClean)
{
    if(wipeClean)
    {
        userInformation.setText(s + "\n");
    }
    else
    {
        postUserMessage(s);
    }
}

public void postUserMessage(String s)
{
    userInformation.appendText(s + "\n");
}

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.

Michael Sims
  • 1,622
  • 10
  • 20
1

NO, But we have alternative in the form of function overloading.

called when no parameter passed

void operation(){

int a = 0;
int b = 0;

} 

called when "a" parameter was passed

void operation(int a){

int b = 0;
//code

} 

called when parameter b passed

void operation(int a , int b){
//code
} 
Umair Khalid
  • 1,961
  • 1
  • 18
  • 25
1

One idea is to use String... args

public class Sample {
   void demoMethod(String... args) {
      for (String arg : args) {
         System.out.println(arg);
      }
   }
   public static void main(String args[] ) {
      new Sample().demoMethod("ram", "rahim", "robert");
      new Sample().demoMethod("krishna", "kasyap");
      new Sample().demoMethod();
   }
}

Output

ram
rahim
robert
krishna
kasyap

from https://www.tutorialspoint.com/Does-Java-support-default-parameter-values-for-a-method

Inês Gomes
  • 2,201
  • 1
  • 16
  • 26
1

If you really want to, you can check it manually by using null:

public MyParameterizedFunction(String param1, int param2, boolean param3)
{
    if(param3 == null) {
        param3 = false;
    }
}

However i heavily recommend using something else, like overloading or a static factory. Maybe you can get away with this, but it can lead to unexcspected behavior. For example you could have an error in your code, so that your boolean never gets a value. In this case you would not get a NullPointerException. Instead it will look like it was set to false, which can be very confusing to debug.

Tobias
  • 183
  • 12
0

You can use the following-

public void mop(Integer x) {
  // Define default values
        x = x == null ? 200 : x;
}
Sobhit Sharma
  • 354
  • 4
  • 27