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

时间:2010-09-10 14:40:18

标签: java constructor initialization

有谁知道为什么你可以使用staticthis()在构造函数的第一行引用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;
    }
}

以下非工作示例:

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;
    }
}

6 个答案:

答案 0 :(得分:16)

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

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

答案 1 :(得分:12)

请参阅Java Language Specification 8.8.7.1。这表明

  

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

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

答案 2 :(得分:1)

我认为这是因为最终的实例变量尚未设置(所以你还没有实例),实例方法可以访问一个。而所有静态初始化都是在构造函数调用之前完成的。

格尔茨, GHAD

答案 3 :(得分:1)

因为当您在构造函数中调用this或super时,您的对象尚未构建。 (您的实例尚未完全初始化)。所以调用实例方法不会产生场景。

答案 4 :(得分:1)

此时未初始化TestNotWorking。问题是:第一个构造函数(TestNotWorking(A aParam))可能会调用super()(它在内部总是这样做),这意味着您将在调用超类的构造函数之前调用方法。这是非法的。

答案 5 :(得分:0)

如果方法是非静态的,则必须在对象上调用它。

在第二个示例中,您需要创建一个类TestNotWorking的对象,并在该对象上调用getAFromB

类似的东西:

object = new TestNotWorking();
object.getAFromB(bParam);