我知道有些特殊的类不适用这个一般性问题,但是对于简单的类,当我们有多个构造函数时,一个的参数是另一个的干净子集,调用构造函数是否更好从列表较短的列表中选择较长的列表,反之亦然?为什么?
public class A {
int x;
int y;
int z;
public A() {
this(0);
}
public A(int x) {
this (x, 0);
}
public A(int x, int y) {
this(x, y, 0);
}
public A(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
// some setup stuff needed for all A
}
}
或者
public class A {
int x;
int y;
int z;
public A(int x, int y, int z) {
this(x, y);
this.z = z;
}
public A(int x, int y) {
this(x);
this.y = y;
}
public A(int x) {
this();
this.x = x;
}
public A() {
// some setup stuff needed for all A
}
}
最佳答案
看看第二个变体:
public A(int x, int y, int z) {
this(x, y);
this.z = z;
}
public A(int x, int y) {
this(x);
this.y = y;
}
public A(int x) {
this();
this.x = x;
}
public A() {
// some setup stuff needed for all A
}
请注意,如果需要 x
的实际值,则无法设置“所有 A 都需要的东西” , y
, z
.解决这个问题的唯一方法是让默认构造函数使用默认值 x
来完成这项工作。 , y
, z
然后使用指定的非默认值在调用构造函数中覆盖其结果。如果这些设置工作有明显的副作用,那是不行的,但即使没有副作用,它也可能对性能产生负面影响,考虑到最坏的情况,A(int x, int y, int z)
构造函数执行该工作四次。
除此之外,还有(至少)三种情况,即使没有这样的设置工作,您的第二个变体也不起作用:
已经explained by Codebender , 参数列表不需要是彼此的子集。
public A(TypeA a) { this(a, DEFAULT_B); } public A(TypeB b) { this (DEFAULT_A, b); } public A(TypeA a, TypeB b) { … }
字段可能是
final
.然后,链中的最后一个构造函数(不调用此类的另一个构造函数)必须初始化所有final
。字段,而委托(delegate)构造函数不允许写入这些final
字段。public class A { final int x, y, z; public A() { this(0); } public A(int x) { this (x, 0); } public A(int x, int y) { this(x, y, 0); } public A(int x, int y, int z) { this.x = x; this.y = y; this.z = z; // optionally, some setup stuff needed for all A } }
一些字段在父类(super class)中定义,需要通过构造函数进行初始化。类似于
final
字段初始化,只有链中的最后一个构造函数可以调用super
构造函数,而其他人不能调用super
构造函数,因此只有知道适当值的构造函数才能成为最后一个。public class A extends B{ int z;// B has x and y public A() { this(0); } public A(int x) { this (x, 0); } public A(int x, int y) { this(x, y, 0); } public A(int x, int y, int z) { super(x, y); this.z = z; // optionally, some setup stuff needed for all A } }
由于在很多情况下第二个变体不起作用,我也不会在工作场景中使用它,因为只要某件事只是一个文体问题,你就应该争取一致性 .
关于Java构造函数链方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31593350/