重载的构造函数调用另一个构造函数,但不是第一个语句

时间:2010-08-02 08:27:05

标签: java constructor overloading

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

编辑:使用辅助方法也存在问题,因为我的某些字段是最终字段,我无法使用辅助方法设置它们。

9 个答案:

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

替代方法是工厂式方法,其中MyClassFactoryMyClass个实例提供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);
 }
}

为获得最佳效果,请制作“常规”构造函数protectedprivate

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