是否可以从另一个(在同一类中,而不是从子类中)调用构造函数?如果是,怎么办?调用另一个构造函数的最佳方法是什么(如果有几种方法)?


当前回答

使用此(参数)。首选模式是从最小构造函数到最大构造函数。

public class Cons {

    public Cons() {
        // A no arguments constructor that sends default values to the largest
        this(madeUpArg1Value,madeUpArg2Value,madeUpArg3Value);
    }

    public Cons(int arg1, int arg2) {
       // An example of a partial constructor that uses the passed in arguments
        // and sends a hidden default value to the largest
        this(arg1,arg2, madeUpArg3Value);
    }

    // Largest constructor that does the work
    public Cons(int arg1, int arg2, int arg3) {
        this.arg1 = arg1;
        this.arg2 = arg2;
        this.arg3 = arg3;
    }
}

您还可以使用最近提倡的valueOf或“of”方法:

public class Cons {
    public static Cons newCons(int arg1,...) {
        // This function is commonly called valueOf, like Integer.valueOf(..)
        // More recently called "of", like EnumSet.of(..)
        Cons c = new Cons(...);
        c.setArg1(....);
        return c;
    }
} 

要调用超级类,请使用super(someValue)。对super的调用必须是构造函数中的第一个调用,否则将出现编译器错误。

其他回答

从另一个构造函数调用构造函数

class MyConstructorDemo extends ConstructorDemo
{
    MyConstructorDemo()
    {
        this("calling another constructor");
    }
    MyConstructorDemo(String arg)
    {
        System.out.print("This is passed String by another constructor :"+arg);
    }
}

也可以使用super()调用调用父构造函数

当我需要从代码内部调用另一个构造函数时(不是在第一行),我通常使用这样的助手方法:

class MyClass {
   int field;


   MyClass() {
      init(0);
   } 
   MyClass(int value) {
      if (value<0) {
          init(0);
      } 
      else { 
          init(value);
      }
   }
   void init(int x) {
      field = x;
   }
}

但大多数情况下,我会尽可能从第一行的简单构造函数调用更复杂的构造函数。对于以上示例

class MyClass {
   int field;

   MyClass(int value) {
      if (value<0)
         field = 0;
      else
         field = value;
   }
   MyClass() {
      this(0);
   }
}

是的,一个类中可以存在任意数量的构造函数,它们可以由另一个构造函数使用this()调用[请不要将this()构造函数调用与this关键字混淆]。this()或this(args)应该是构造函数中的第一行。

例子:

Class Test {
    Test() {
        this(10); // calls the constructor with integer args, Test(int a)
    }
    Test(int a) {
        this(10.5); // call the constructor with double arg, Test(double a)
    }
    Test(double a) {
        System.out.println("I am a double arg constructor");
    }
}

这被称为构造函数重载。请注意,对于构造函数,只有重载概念才适用,而不是继承或重写。

我会告诉你一个简单的方法

构造函数有两种类型:

默认构造函数参数化构造函数

我将在一个示例中解释

class ConstructorDemo 
{
      ConstructorDemo()//Default Constructor
      {
         System.out.println("D.constructor ");
      }

      ConstructorDemo(int k)//Parameterized constructor
      {
         this();//-------------(1)
         System.out.println("P.Constructor ="+k);       
      }

      public static void main(String[] args) 
      {
         //this(); error because "must be first statement in constructor
         new ConstructorDemo();//-------(2)
         ConstructorDemo g=new ConstructorDemo(3);---(3)    
       }
   }                  

在上面的示例中,我展示了3种类型的调用

this()调用必须是构造函数中的第一条语句这是无名称对象。这将自动调用默认构造函数。3.这将调用参数化构造函数。

注:这必须是构造函数中的第一条语句。

[注:我只想添加一个方面,这是我在其他答案中没有看到的:如何克服this()必须位于第一行的要求的限制。]

在Java中,可以通过this()从构造函数调用同一类的另一个构造函数。但是请注意,这必须在第一行。

public class MyClass {

  public MyClass(double argument1, double argument2) {
    this(argument1, argument2, 0.0);
  }

  public MyClass(double argument1, double argument2, double argument3) {
    this.argument1 = argument1;
    this.argument2 = argument2;
    this.argument3 = argument3;
  }
}

这必须出现在第一行看起来是一个很大的限制,但您可以通过静态方法构造其他构造函数的参数。例如:

public class MyClass {

  public MyClass(double argument1, double argument2) {
    this(argument1, argument2, getDefaultArg3(argument1, argument2));
  }

  public MyClass(double argument1, double argument2, double argument3) {
    this.argument1 = argument1;
    this.argument2 = argument2;
    this.argument3 = argument3;
  }

  private static double getDefaultArg3(double argument1, double argument2) {
    double argument3 = 0;

    // Calculate argument3 here if you like.

    return argument3;

  }

}