我有以下课程:
class Pair
{
String car;
Integer cdr;
public Pair () {}
public Pair (String car) { this.car = car; }
public Pair (Integer cdr) { this.cdr = cdr; }
public Pair (String car, Integer cdr)
{
this(car);
this(cdr);
}
}
Run Code Online (Sandbox Code Playgroud)
该类包含两个可选值,我想提供所有可能的构造函数排列.第一个版本不初始化任何内容,第二个版本仅初始化第一个值,第三个版本仅初始化第二个值.
最后一个构造函数是第二个和第三个的组合.但是不可能把它写下来,因为代码失败了.
constructor.java:13: call to this must be first statement in constructor
this(cdr);
^
1 error
是否可以编写最后一个没有任何代码冗余的构造函数(也没有调用相同的setter方法)?
Seb*_*edl 51
通常,具有较少参数的构造函数应该调用具有更多参数的构造函数.
public Pair() {}
public Pair(String car) { this(car, null); }
public Pair(Integer cdr) { this(null, cdr); }
public Pair(String car, Integer cdr) { this.car = car; this.cdr = cdr; }
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 19
将构造函数链接到相反的方向,最具体的是设置所有字段的构造函数:
public Pair() {
this(null, null); // For consistency
}
public Pair(String car) {
this(car, null);
}
public Pair(Integer cdr) {
this(null, cdr);
}
public Pair (String car, Integer cdr) {
this.car = car;
this.cdr = cdr;
}
Run Code Online (Sandbox Code Playgroud)
那样:
顺便说一句,我强烈建议您将字段设为私有(可能是最终字段),并为它们提供更有意义的名称.
注意这样,如果你有(比方说)5个参数和一个构造函数有3个,一个有4个,一个有5个,你可以选择从3 - > 4 - > 5链接,或者你可以直接从3 - > 5.
此外,您可能希望完全删除单参数构造函数 - 而使用静态方法会更具可读性,您可以在其中指定名称中的含义:
public static Pair fromCar(String car) {
return new Pair(car, null);
}
public static Pair fromCdr(Integer cdr) {
return new Pair(null, cdr);
}
Run Code Online (Sandbox Code Playgroud)
或者在我喜欢的含义命名中:
public static Pair fromFirst(String first) {
return new Pair(first, null);
}
public static Pair fromSecond(Integer second) {
return new Pair(null, second);
}
Run Code Online (Sandbox Code Playgroud)
此时,您可以使Pair类通用,而不必担心如果两个类型参数相同,将调用哪个构造函数.此外,任何阅读代码的人都可以理解将要构建的内容,而无需检查参数的类型.
您可能正在寻找构建器模式.
除此之外,这种模式允许你不要有涵盖所有情况的bazillion构造函数.根据您的情况,这可能是:
@Immutable // see JSR 305
public final class Pair
{
private final String car;
private final integer cdr;
private Pair(final Builder builder)
{
car = builder.car;
cdr = builder.cdr;
}
public static Builder newBuilder()
{
return new Builder();
}
// whatever other methods in Pair, including accessors for car and cdr, then:
@NotThreadSafe // see JSR 305
public final class Builder
{
private String car;
private int cdr;
private Builder()
{
}
public Builder withCar(final String car)
{
this.car = car;
return this;
}
public Builder withCdr(final int cdr)
{
this.cdr = cdr;
return this;
}
public Pair build()
{
return new Pair(this);
}
}
}
Run Code Online (Sandbox Code Playgroud)
样品用法:
final Pair newPair = Pair.newBuilder.withCar("foo").withCdr(1).build();
Run Code Online (Sandbox Code Playgroud)
优势:Pair现在是不变的!
class Pair
{
String car;
Integer cdr;
public Pair () {}
public Pair (String car) {
this(car, null)
}
public Pair (Integer cdr) {
this(null, cdr);
}
public Pair (String car, Integer cdr) {
this.car = car;
this.cdr = cdr;
}
}
Run Code Online (Sandbox Code Playgroud)