[英]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");
並且構造函數必須在兩種情況下都工作,即使參數列表被截斷(在后一種情況下,一些默認值被賦值給value和numberOfCopies )。 當然,我可以編寫六個構造函數(對於可能的參數數量,從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.