重载构造函数调用其他构造函数,但不作为第一个语句
我在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
private
或private
。
您可以将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); } }