重载构造函数调用其他构造函数,但不作为第一个语句

我在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“在行”。 我想可能会创建一个构造辅助方法,它将进行实际构造,但我不确定它是如此“漂亮”……

编辑 :使用辅助方法也是有问题的,因为我的一些字段是最终的,我不能使用辅助方法设置它们。

通常使用另一种常用方法 – 如您所建议的“建筑助手”。

 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); } } 

我绝对更喜欢第一种选择。

虽然我更喜欢其他几个答案指出的工厂方法选项,但我想建议另一个选项:您可以使用静态方法来计算其他参数:

 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 } } 

下一个可能的解决方案是Factory方法 这些静态方法可以重载,计算后可以调用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 ); } } 

编辑:当您有最终字段时,此方法也是理想的

帮助器和工厂选项非常好。

还有一个:

 public MyClass(int arg1) { this(arg1, calculateArg2(), calculateArg3()); } private static int calculateArg2() {..} private static int calculateArg3() {..} 

使用标记值“丢失”

 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 privateprivate

您可以将MyClass(arg1, arg2, arg3)的代码移动到helper方法(将其命名为Init或其他),然后在两个构造函数中调用此方法。

另一种方式是这样的:

 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 } } 

作为给出答案的替代方法,最简单的方法是将参数计算重构为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); } } 

您可以创建一个调用构造函数的工厂方法 :

 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); } }