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


当前回答

是的,一个类中可以存在任意数量的构造函数,它们可以由另一个构造函数使用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");
    }
}

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

其他回答

您可以使用“this”关键字从同一类的另一个构造函数中创建构造函数。示例-

class This1
{
    This1()
    {
        this("Hello");
        System.out.println("Default constructor..");
    }
    This1(int a)
    {
        this();
        System.out.println("int as arg constructor.."); 
    }
    This1(String s)
    {
        System.out.println("string as arg constructor..");  
    }

    public static void main(String args[])
    {
        new This1(100);
    }
}

输出-字符串作为arg构造函数。。默认构造函数。。int作为arg构造函数。。

最初来自米尔科·克莱姆(Mirko Klemm)的回答,为了解决这个问题,稍作修改:

为了完整起见:还有实例初始化块,它总是在调用任何其他构造函数之前执行。它只是由类定义正文中某个位置的语句块“{…}”组成。你甚至可以有不止一个。你不能调用它们,但如果你想在构造函数之间重用一些代码,它们就像“共享构造函数”代码,类似于调用方法。

所以在你的情况下

{ 
  System.out.println("this is shared constructor code executed before the constructor");
  field1 = 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;

  }

}

是的,可以使用this()从另一个构造函数调用一个构造函数

class Example{
   private int a = 1;
   Example(){
        this(5); //here another constructor called based on constructor argument
        System.out.println("number a is "+a);   
   }
   Example(int b){
        System.out.println("number b is "+b);
   }

我知道这个问题有很多例子,但我把我的发现放在这里是为了分享我的想法。有两种方法可以链接构造函数。在同一类中,可以使用此关键字。在继承中,需要使用超级关键字。

    import java.util.*;
    import java.lang.*;

    class Test
    {  
        public static void main(String args[])
        {
            Dog d = new Dog(); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.
            Dog cs = new Dog("Bite"); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.

            // You need to Explicitly tell the java compiler to use Argument constructor so you need to use "super" key word
            System.out.println("------------------------------");
            Cat c = new Cat();
            Cat caty = new Cat("10");

            System.out.println("------------------------------");
            // Self s = new Self();
            Self ss = new Self("self");
        }
    }

    class Animal
    {
        String i;

        public Animal()
        {
            i = "10";
            System.out.println("Animal Constructor :" +i);
        }
        public Animal(String h)
        {
            i = "20";
            System.out.println("Animal Constructor Habit :"+ i);
        }
    }

    class Dog extends Animal
    {
        public Dog()
        {
            System.out.println("Dog Constructor");
        }
        public Dog(String h)
        {
            System.out.println("Dog Constructor with habit");
        }
    }

    class Cat extends Animal
    {
        public Cat()
        {
            System.out.println("Cat Constructor");
        }
        public Cat(String i)
        {
            super(i); // Calling Super Class Paremetrize Constructor.
            System.out.println("Cat Constructor with habit");
        }
    }

    class Self
    {
        public Self()
        {
            System.out.println("Self Constructor");
        }
        public Self(String h)
        {
            this(); // Explicitly calling 0 args constructor. 
            System.out.println("Slef Constructor with value");
        }
    }