我在java中使用多个构造函数时遇到了一些麻烦。
我想做的是这样的事情:
public class MyClass {
// first constructor
public MyClass(arg1, arg2, arg3) {
// do some construction
}
// second constructor
public MyClass(arg1) {
// do some stuff to calculate arg2 and arg3
this(arg1, arg2, arg3);
}
}
但我不能,因为第二个构造函数不能调用另一个构造函数,除非它是第一行。
这种情况的常见解决方案是什么? 我无法计算arg2和arg3“在行”。我想可能会创建一个构造辅助方法,它将进行实际构造,但我不确定它是如此“漂亮”......
编辑:使用辅助方法也存在问题,因为我的某些字段是最终字段,我无法使用辅助方法设置它们。
答案 0 :(得分:23)
通常使用另一种常用方法 - 正如您所建议的“建筑助手”。
public class MyClass {
// first constructor
public MyClass(arg1, arg2, arg3) {
init(arg1, arg2, arg3);
}
// second constructor
public MyClass(int arg1) {
// do some stuff to calculate arg2 and arg3
init(arg1, arg2, arg3);
}
private init(int arg1, int arg2, int arg3) {
// do some construction
}
}
替代方法是工厂式方法,其中MyClassFactory
为MyClass
个实例提供MyClass
个实例,而public class MyClass {
// constructor
public MyClass(arg1, arg2, arg3) {
// do some construction
}
}
public class MyClassFactory {
public static MyClass MakeMyClass(arg1, arg2, arg3) {
return new MyClass(arg1, arg2, arg3);
}
public static MyClass MakeMyClass(arg1) {
// do some stuff to calculate arg2 and arg3
return new MyClass(arg1, arg2, arg3);
}
}
只有一个构造函数:
{{1}}
我绝对更喜欢第一种选择。
答案 1 :(得分:9)
下一个可能的解决方案是Factory method。这些静态方法可以重载,计算后可以调用private / protected构造函数
public class MyClass {
private MyClass( arg1, arg2, arg3 ) {
// do sth
}
public static MyClass getInstance( arg1 ) {
// calculate arg2,3
return new MyClass( arg1, arg2, arg3 );
}
public static MyClass getInstance( arg1, arg2, arg3 ) {
return new MyClass( arg1, arg2, arg3 );
}
}
编辑:如果您有最终字段
,此方法也是理想选择答案 2 :(得分:8)
虽然我更喜欢其他几个答案指出的工厂方法选项,但我想建议另一个选项:您可以使用静态方法来计算其他参数:
public class MyClass {
public MyClass(int arg1, int arg2, int arg3) {
// do some construction
}
public MyClass(int arg1) {
//call to this() must be the first one
this(arg1, calculateArg2(arg1), calculateArg3());
//you can do other stuff here
}
private static int calculateArg2(int arg1) {
//calc arg2 here
}
private static int calculateArg3() {
//calc arg3 here
}
}
答案 3 :(得分:4)
帮手和工厂选项非常好。
还有另一个:
public MyClass(int arg1) {
this(arg1, calculateArg2(), calculateArg3());
}
private static int calculateArg2() {..}
private static int calculateArg3() {..}
答案 4 :(得分:3)
使用'缺失'的标记值
public class MyClass {
public MyClass(arg1, arg2, arg3) {
// do some stuff to calculate arg2 and arg3 if they are the missing values
// do some construction
}
public MyClass(arg1) {
this(arg1, null, null);
}
}
为获得最佳效果,请制作“常规”构造函数protected
或private
。
答案 5 :(得分:0)
您可以将MyClass(arg1, arg2, arg3)
的代码移动到辅助方法(将其命名为Init
或其他内容),然后在两个构造函数中调用此方法。
答案 6 :(得分:0)
你可以创建一个调用构造函数的factory method:
public class MyClass {
// first constructor
public MyClass(arg1, arg2, arg3) {
// do some construction
}
// second constructor as factory method
public static createMyClassAndDoFunkyStuff(int arg1) {
// do some stuff to calculate arg2 and arg3
return new MyClass(arg1, arg2, arg3);
}
}
答案 7 :(得分:0)
另一种方式是:
public class MyClass {
// first constructor
public MyClass(arg1, arg2, arg3) {
// do some construction
doSomeStuffToArg3Arg3(arg2, arg3)
}
// second constructor
public MyClass(int arg1) {
this(arg1, arg2, arg3);
}
private void doSomeStuffToArg3Arg3(int arg2, int arg3) {
// do some stuff to calculate arg2 and arg3
}
}
答案 8 :(得分:0)
作为给出答案的替代方法,最简单的方法是将参数计算重构为3参数构造函数;
public class MyClass {
// first constructor
public MyClass(arg1, arg2, arg3) {
if (null == arg2) {
// calculate arg2
}
if (null == arg3) {
// calculate arg3
}
// do some construction
}
// second constructor
public MyClass(arg1) {
this(arg1, null, null);
}
}