java-当我在构造函数中调用方法时会发生什么?

时间:2017-04-23 12:30:19

标签: java constructor polymorphism override

class Glyph {
    void draw() {
        print("Glyph.draw()");
    }

    Glyph() {
        print("Glyph() before draw()");
        draw();
        print("Glyph() after draw()");
    }

}
class RoundGlyph extends Glyph{
    private int radius = 1;
    RoundGlyph(int r){
        radius = r;
        print("RoundGLyph.draw(), radius = " + radius);
    }
    void draw(){
        print("radius:" + radius);
    }
    public static void main(String[] args){
        new RoundGlyph(5);

    }

}

//Glyph() before draw()
radius:0
Glyph() after draw()
RoundGLyph.draw(), radius = 5

上面的代码。

由于draw()不是静态的,因此必须有一个隐含的参数(this)。虽然在这种情况下,在Glyph的构造函数中调用draw(),所以我想知道这个“隐式参数”是什么。 据我所知,当我调用t.f()时,t为t类型,编译器会将其变为T.f(t)。

结果表明,在我看来,它是一个RoundGlyph作为这个参数提供。但是这怎么可能?显然,调用draw()时不会创建RoundGlyph。

3 个答案:

答案 0 :(得分:6)

您正在构建RoundGLyph实例。 RoundGLyph的构造函数调用超类的构造函数 - Glyph - 调用draw()方法。由于RoundGLyph会覆盖Glyph draw()方法,Glyph构造函数会调用RoundGLyph draw()方法,该方法会打印{ {1}}。

但是,由于在radius实例完全初始化之前调用它(RoundGLyph构造函数的主体尚未执行,甚至RoundGLyph初始化也没有&#39}。尚未执行),radius = 1变量仍保留默认值radius。由于Java语言的这种行为,建议不要在构造函数中调用非final方法(因为它们可以被覆盖)。

答案 1 :(得分:1)

将正常调用方法。这次指向的对象是不完美的,但是这个指针在那里,所以没有异常,但建议不要这样做,因为在不完美的对象上调用实例方法是危险的。

答案 2 :(得分:0)

在这种情况下,正在调用超级构造函数,即调用Glyph构造函数。现在发生的棘手的事情是调用drawG(方法)在RoundGlyph中被覆盖,因此Glyph调用RoundGlyph中的覆盖版本,打印半径变量,但同样奇怪的是,0被打印出来因为子构造函数语句直到现在才执行,所以因为它是一个基元,所以打印默认值0。如果它是某个对象,那么就会打印出null。希望这能澄清它。