簡體   English   中英

如何為不同類型的可變數量的參數編寫Java構造函數?

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

我必須為類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");

並且構造函數必須在兩種情況下都工作,即使參數列表被截斷(在后一種情況下,一些默認值被賦值給valuenumberOfCopies )。 當然,我可以編寫六個構造函數(對於可能的參數數量,從0到5,假設參數始終遵循上述順序,而不會混淆),但應該有更聰明的方法。 我知道我可以聲明構造函數

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

然后將params元素轉換為相應的類。 這可能會有效,但我總是要檢查使用“if”條件為構造函數提供了多少參數,以便決定是否在未提供相應參數的情況下為變量分配默認值,或者使用提供的值(如果是給出。 這一切看起來都很難看。 因此,問題很簡單:如果提供的參數列表長度不同且參數類型不同,構建構造函數(或其他方法)的方法是什么?

這可能適用於建造者模式

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();

而不是弄亂Object[]去構造函數重用。

提供所有可能的構造函數並在內部使用它們

只是一個前任;

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

到目前為止還沒有其他工作。

如果傳遞的項目無關緊要,您可以使用varargs:

public Stamp(Object... obj) {

}

但是,根據您的示例,聽起來您想要添加構造函數重載。 由於所有數據似乎都有意義並代表一個特定的東西,我只是像這樣重載:

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

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

實際上,正如其他人所說,可能的解決方案是使用this()調用重用構造函數。

如果訂單是可變的並且您無法分辨給出哪一個以及哪個不是,那么Object[]將是不夠的。 你需要一個Map<String, Object> ,你需要為它們編寫顯式轉換。 使用Reflection也可能有更好的方法來做到這一點,但我還沒有完全弄明白。

因此,“簡單”的方法將是而不是

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

但我真的認為其他解決方案更好一點,因為它們占用的代碼更少,本身就是類型安全的(不太可能搞亂),老實說,我會選擇Ian Roberts所說的builder pattern ,我真的很喜歡那個答案。

使用方法重載,java支持這個。 意味着您可以使用不同的參數在同一個類中編寫相同的方法,只需使用復制粘貼並制作多個方法。:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM