Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a Java constructor for variable number of arguments of different types?

I have to write a constructor for a class Stamp. The constructor is supposed to take up to five arguments of types String, int, and double. So, the constructor would look like this:

public Stamp(String code, int year, String country, double value, int numberOfCopies){...}

The problem is, as the object of the class Stamp is being created, not all the parameters may be provided, i.e., an object can be declared as

Stamp stamp = new Stamp("some_code", 1991, "Burkina Faso", 50, 1000);

as well as

Stamp stamp = new Stamp("some_code", 1991, "Burkina Faso");

and the constructor has to work in both cases, even if the list of arguments is truncated (in the latter case, some default values are assigned to value and numberOfCopies). Of course, I can just write six constructors (for the possible number of parameters from 0 to 5, assuming that the parameters always follow the order described above, without mixing up), but there should be a smarter way. I know I can probably declare the constructor like

public Stamp(Object[] params){...}

and then cast the elements of params into corresponding classes. This will probably work but I will always have to check how many parameters are provided for the constructor using "if" conditions in order to decide whether to assign default values to variables if the corresponding parameters are not provided or use the provided values if those are given. This all seems pretty ugly. Thus, the question is brief: what is the way to build a constructor (or some other method) if the list of provided parameters varies in length and the types of parameters are different?

like image 824
Konstantin Popov Avatar asked Jul 04 '14 12:07

Konstantin Popov


2 Answers

This may be a suitable use for a builder pattern

public class Stamp {

  public static class Builder {
    // default values
    private String code = "default code"
    private int year = 1900;
    // etc.

    public Builder withCode(String code) {
      this.code = code;
      return this;
    }
    public Builder withYear(int year) {
      this.year = year;
      return this;
    }
    // etc.

    public Stamp build() {
      return new Stamp(code, year, country, value, numberOfCopies);
    }
  }

  public Stamp(String code, int year, String country, double value,
      int numberOfCopies){...}
}

The construction process then becomes

Stamp s = new Stamp.Builder()
                .withCode("some_code")
                .withYear(1991)
              .build();

This way the arguments are no longer order-dependent - you could equivalently say

Stamp s = new Stamp.Builder()
                .withYear(1991)
                .withCode("some_code")
              .build();
like image 65
Ian Roberts Avatar answered Oct 08 '22 09:10

Ian Roberts


Instead of messing up with Object[] go with constructor reuse.

Provide all possible constructors and use them internally

Just an ex;

public Stamp(String code, int year)
{
    this(code, "", year,0,0); //calling your main constructor with missed values.
}

No other work around as of now.

like image 44
Suresh Atta Avatar answered Oct 08 '22 11:10

Suresh Atta