javaconstructor-overloading

How to call the base constructor of an object from overloaded varargs constructor?


I have a simple class with a constructor of all available fields and i want to add an overloaded constructor with varargs to allow the creating of objects even if some fields are unknown.

class FooClass {
    int id;
    String first;
    String second;
    String third;

    FooClass(final int id, final String first, final String second, final String third) {
        this.id = id;
        this.first = first;
        this.second = second;
        this.third = third;
    }

    FooClass(final int id, final String... myStrings){
        if(myStrings.length == 1) {
            this.id     = id;
            this.first  = myStrings[0];
        } else if (myStrings.length == 2) {
            this.id     = id;
            this.first  = myStrings[0];
            this.second = myStrings[1];
        } else {
            this.id     = id;
            this.first  = myStrings[0];
            this.second = myStrings[1];
            this.third  = myStrings[2];
        }
    }
}

I wanted to refactor the second constructor to avoid repeating this.id, this.first ... as follows, but I am getting a compile error

FooClass(final int id, final String... myStrings){
        if(myStrings.length == 1) {
            this(id, myStrings[0], null, null);
        } else if (myStrings.length == 2) {
            this(id, myStrings[0], myStrings[1], null);
        } else {
            this(id, myStrings[0], myStrings[1], myStrings[2]);
        }
    }

The error is:

Call to 'this()' must be first statement in constructor body

What is the correct way to call the base constructor from the varargs constructor with null values? Or a better way to implement what I described above?


Solution

  • In Java, a call to this or super MUST be the first line of the constructor.

    class FooClass {
        int id;
        String first;
        String second;
        String third;
    
        FooClass(final int id, final String first) {
            this(id, first, null);
        }
        
        FooClass(final int id, final String first, final String second) {
            this(id, first, second, null);
        }
        
        FooClass(final int id, final String first, final String second, final String third) {
            this.id = id;
            this.first = first;
            this.second = second;
            this.third = third;
        }
        
    }
    

    One approach to get similar functionality to varargs is to simply write multiple constructors that chain upwards with default values passed.

    This could get cumbersome though if the number of parameters is high, but the example is only using 3 String values.

    Here is what calling them would look like:

    //Example calls
    public static void main(String [] args) {
        FooClass foo1 = new FooClass(1, "foo1");
        FooClass foo2 = new FooClass(2, "foo1", "foo2");
        FooClass foo3 = new FooClass(3, "foo1", "foo2", "foo3");
    }