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


当前回答

可以通过this(…)关键字(当需要从同一类调用构造函数时)或super(…)关键词调用另一个构造函数(当您需要从超类调用构造函数时)。

但是,这样的调用必须是构造函数的第一条语句。要克服这个限制,请使用这个答案。

其他回答

您可以使用“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构造函数。。

我更喜欢这种方式:

    class User {
        private long id;
        private String username;
        private int imageRes;

    public User() {
        init(defaultID,defaultUsername,defaultRes);
    }
    public User(String username) {
        init(defaultID,username, defaultRes());
    }

    public User(String username, int imageRes) {
        init(defaultID,username, imageRes);
    }

    public User(long id, String username, int imageRes) {
        init(id,username, imageRes);

    }

    private void init(long id, String username, int imageRes) {
        this.id=id;
        this.username = username;
        this.imageRes = imageRes;
    }
}

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

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

所以在你的情况下

{ 
  System.out.println("this is shared constructor code executed before the constructor");
  field1 = 3;
}

还有一个“静态”版本用于初始化静态成员:“静态{…}”

是的,有可能:

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

    public Foo(int x) {
        this.x = x;
    }
}

要链接到特定的超类构造函数而不是同一类中的构造函数,请使用super而不是this。请注意,您只能链接到一个构造函数,并且它必须是构造函数主体中的第一条语句。

另请参阅这个相关的问题,它是关于C#的,但在相同的原则适用的地方。

正如大家已经说过的,您使用this(…),这称为显式构造函数调用。

但是,请记住,在这样的显式构造函数调用语句中,您可能不会引用

任何实例变量或任何实例方法或该类或任何超类中声明的任何内部类,或此或超级的

如JLS(§8.8.7.1)所述。