Andrew Maddison

Flowerchild.

Overloaded Methods, Varargs, Single Arguments and Recursion in Java

This is another “documenting my own stupidity” post. I’m hoping the public self-ridicule will help stop me from being so short sighted in the first place.

I’m sure lots of people use the following pattern. You write a method that takes a heap of arguments, but which can have some defaults. You then introduce one or more overloads, with progressively fewer arguments, and sensible defaults filled in.

To avoid duplication of your actual logic, the overloads only add the defaults, and then call the original, many argumented method. For example:

Original pattern:

1
2
3
4
5
6
7
8
9
public String doSomething(){
    //No logic here, just a call to the next method down with a default.
    return doSomething("default-value");
}

public String doSomething(String argument) {
    //does something - very complicated, you don't want to duplicate this.
    return argument + " or summat";
}

So that was fine, But then things moved on, and I needed to introduce a little more complexity in the form of an unknown number of arguments using varargs. So I simply added a new method, migrated the logic and refactored to something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//we refactor the other methods - still don't want duplication
public String doSomething(){
    //No logic here, just a call to the next method down with a default.
    return doSomething("default-value");
}

public String doSomething(String argument) {
    //want to call the varargs based method below:
    return doSomething(argument);
    //Hmm - that's not going to work - it's just going to recurse.
}

public String doSomething(String ... lotsOfArguments) {
    //does something - even more very extremely complicated, and you still don't want duplication
    return StringUtils.join(authors, ",") + " or summat";
}

The middle method in the above snippet doesn’t work (and throws infinite recursion warnings) as it simply calls itself, rather than the varargs method with a single argument.

What confused me is that I googled about a bit, and couldn’t find any discussion of what to do in this case, so I tried the following, and felt pretty pleased with myself.

1
2
3
4
5
public String doSomething(String argument) {
    //want to call the varargs based method with the logic in:
    return doSomething(new String[]{argument});
    //take that Java
}

But of course – I was completely missing the point. I didn’t need the single argument overload as calls with a single argument already call the varargs overload! So it just needs deleting – and happy days.

1
2
3
4
5
6
7
8
9
10
//Delete the single string argument - it was a rudundant fossil anyway.
    public String doSomething(){
        //No logic here, just a call to the next method down with a default.
        return doSomething("default-value");
    }

    public String doSomething(String ... lotsOfArguments) {
        //does something - even more very extremely complicated, and you still don't want duplication
        return StringUtils.join(authors, ",") + " or summat";
    }
1
2
//calling code: works fine
String resut = doSomething("single string");

Works fine if you delete the single argument method. Of course. Face palm.

Comments