为什么我不能在显式调用构造函数时引用实例方法?

Koe*_*box 36 java constructor initialization

有谁知道为什么你可以static使用this()super()但不是非静态方法引用构造函数的第一行中的方法?

考虑以下工作:

public class TestWorking{
    private A a = null;
    public TestWorking(A aParam){
       this.a = aParam;
    }

    public TestWorking(B bParam)
    {
        this(TestWorking.getAFromB(bParam));
    }

    //It works because its marked static.
    private static A getAFromB(B param){
        A a = new A();
        a.setName(param.getName());
        return a;
    }
}
Run Code Online (Sandbox Code Playgroud)

以下非工作示例:

public class TestNotWorking{
    private A a = null;
    public TestNotWorking(A aParam){
       this.a = aParam;
    }

    public TestNotWorking(B bParam)
    {
        this(this.getAFromB(bParam));
    }

    //This does not work. WHY???
    private A getAFromB(B param){
        A a = new A();
        a.setName(param.getName());
        return a;
    }
}
Run Code Online (Sandbox Code Playgroud)

amo*_*fis 18

非静态方法是实例方法.这只能在现有实例中访问,并且当您在构造函数中时,实例仍然不存在(它仍在构建中).

为什么会这样?因为实例方法可以访问实例(非静态)字段,这些字段在不同的实例中可以具有不同的值,因此在现有的完成实例上调用此类方法没有意义.

  • 这很接近,但并不准确.当你在构造函数中时,实例*do*存在,你*可以*对它们调用实例方法.但是,在超类的构造函数完成之前,你无法做到这一点.如果你想在你自己的构造函数中调用它们,那很好,但是必须完成超类. (31认同)
  • @dannail 首先创建实例(即分配空间),然后构造函数按从“Object”到最派生子类的顺序运行。如果可以在超类的构造函数完成之前调用方法,则它们可以对部分初始化的字段进行操作,这可能会违反预期条件。 (2认同)

Mar*_*arc 12

请参阅Java语言规范8.8.7.1.这说明了这一点

构造函数体中的显式构造函数调用语句可能不引用此类或任何超类中声明的任何实例变量或实例方法或内部类,或者使用thissuper在任何表达式中; 否则,发生编译时错误.

这是因为在创建实例之前无法调用实例方法.顺便说一句,以后可以在构造函数中调用实例方法(尽管不是解决方案).