如何为不同类型的变量数编写Java构造函数?
我必须为类戳编写一个构造函数。构造函数应该最多接受五个类型为String、int和double的参数。因此,构造函数将如下所示:如何为不同类型的变量数编写Java构造函数?,java,constructor,Java,Constructor,我必须为类戳编写一个构造函数。构造函数应该最多接受五个类型为String、int和double的参数。因此,构造函数将如下所示: public Stamp(String code, int year, String country, double value, int numberOfCopies){...} 问题是,在创建类戳记的对象时,可能不会提供所有参数,即对象可以声明为 Stamp stamp = new Stamp("some_code", 1991, "Burkina Faso",
public Stamp(String code, int year, String country, double value, int numberOfCopies){...}
问题是,在创建类戳记的对象时,可能不会提供所有参数,即对象可以声明为
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 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) {
//...
}
这可能适用于生成器模式
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();
使用方法重载,java支持这一点。
这意味着您可以使用不同的参数在同一个类中编写相同的方法,只需使用复制粘贴并生成多个方法。事实上,正如其他人所述,一个可能的解决方案是使用
this()
调用重用构造函数
如果顺序是可变的,而您无法分辨哪个是给定的,哪个不是,那么对象[]
就不够了。您需要一个映射
,并且需要为它们编写显式转换。也许还有更好的方法可以通过反射来实现,但我还没有完全弄清楚
因此,“简单”的方法应该是
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...
}
公共枚举StampProperties
{
代码(“代码”),
年份(“年度”),
国家(“国家”),
价值(“价值”),
份数(“份数”);
私有字符串标识符;
专用StampProperties(字符串标识符)
{
this.identifier=标识符;
}
公共布尔c(字符串id)
{
返回标识符.equals(id);
}
}
公众邮票(地图参数)
{
for(字符串:params.keySet())
{
mapProperty(参数、字符串);
}
}
私有void映射属性(映射参数、字符串标识符)
{
Object Object=params.get(标识符);
if(StampProperties.CODE.c(标识符))
{
this.code=(字符串)对象;
}
else if(StampProperties.YEAR.c(标识符))
{
this.year=((整数)对象).intValue();
}
否则如果。。。
}
但我真的认为其他解决方案要好一点,因为它们使用更少的代码,本质上是类型安全的(不太可能出错),老实说,我会选择Ian Roberts所说的
构建器模式,我真的很喜欢这个答案。可能重复阅读[1][1]这篇文章。我认为这有一个解决办法。[1] :Groovy语言对于这类事情有很好的语法,您可以定义一个方法,该方法采用映射
,然后使用“命名参数”调用它,例如makeStamp(年份:1991,代码:“some_code”)
@IanRoberts Groovy是类型化语言吗?最困难的部分是根据变量的类型或类映射变量,并修改正确的变量。我一直在思考这个问题,但我还没想好。我以后可能会在家里修改它。在public Builder with code()中,返回类型是什么?它如何返回而不出错?