如何为不同类型的可变数量的参数编写Java构造函数?

时间:2014-07-04 12:04:59

标签: java constructor

我必须为类Stamp编写构造函数。构造函数应该采用最多五个类型为String,int和double的参数。所以,构造函数看起来像这样:

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

问题是,由于正在创建Stamp类的对象,因此不能提供所有参数,即,可以将对象声明为

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

以及

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

并且构造函数必须在两种情况下工作,即使参数列表被截断(在后一种情况下,一些默认值被分配给 value numberOfCopies )。当然,我可以编写六个构造函数(对于可能的参数数量,从0到5,假设参数始终遵循上述顺序,而不会混淆),但应该有更聪明的方法。我知道我可以声明像

这样的构造函数
public Stamp(Object[] params){...}

然后将params的元素转换为相应的类。这可能会有效,但我总是要检查使用"为什么提供给构造函数的参数;如果"条件,以决定是否在未提供相应参数的情况下为变量分配默认值,或者如果给出了这些值,则使用提供的值。这一切看起来都很难看。因此,问题很简单:如果提供的参数列表长度不同且参数类型不同,构建构造函数(或其他方法)的方法是什么?

5 个答案:

答案 0 :(得分:8)

这可能适用于构建器模式

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){...}
}

然后构建过程变为

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

这样,参数不再依赖于顺序 - 您可以等效地说

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

答案 1 :(得分:5)

而不是弄乱Object[]去构造函数重用。

提供所有可能的构造函数并在内部使用它们

只是前任;

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

目前还没有其他工作。

答案 2 :(得分:0)

如果传递的项目无关紧要,您可以使用varargs:

public Stamp(Object... obj) {

}

但是,根据您的示例,听起来您想要添加构造函数重载。由于所有数据似乎都具有意义并且代表了特定的东西,所以我会简单地重载:

public Stamp(String code, int year) {
    this(code, year, "Burkina Faso");
}

public Stamp(String code, int year, String location) {
    //...
}

答案 3 :(得分:0)

事实上,正如其他人所说,可能的解决方案是使用this()调用重用构造函数。

如果订单是可变的,并且您无法分辨哪一个是哪一个,哪一个不是,那么Object[]就不够了。您需要Map<String, Object>,并且需要为它们编写显式转换。使用Reflection也可能有更好的方法来做到这一点,但我还没有完全弄明白。

所以&#34;简单&#34;方法是而不是

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

你会有

public enum StampProperties
{
    CODE("code"),
    YEAR("year"),
    COUNTRY("country"),
    VALUE("value"),
    NUMBER_OF_COPIES("numberOfCopies");

    private String identifier;

    private StampProperties(String identifier)
    {
        this.identifier = identifier;
    }

    public boolean c(String id)
    {
        return identifier.equals(id);
    }
}

public Stamp(Map<String, Object> params)
{
    for(String string : params.keySet())
    {
        mapProperty(params, string);
    }
}

private void mapProperty(Map<String, Object> params, String identifier)
{
    Object object = params.get(identifier);
    if(StampProperties.CODE.c(identifier))
    {
         this.code = (String) object;
    }
    else if(StampProperties.YEAR.c(identifier))
    {
         this.year = ((Integer) object).intValue();
    }
    else if...
}

但我真的认为其他解决方案更好一些,因为它们占用的代码更少,本质上是类型安全的(不太可能搞乱),老实说,我会选择builder patternIan Roberts说明,我真的很喜欢这个答案。

答案 4 :(得分:-1)

使用方法重载,java支持这个。 意味着您可以使用不同的参数在同一个类中编写相同的方法,只需使用复制粘贴并制作多个方法。:)