简体   繁体   中英

java-What happens when I call a method in constructor?

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

The code being above.

As draw() is not static, there must be a implicit parameter(this) given to it. While in this case, draw() is called in the constructor of Glyph, so I wonder what this "implicit parameter" is. As I know when I call tf(), with t of type T , the compiler will turn it into Tf(t).

As the result suggests, it seems to me that it is an RoundGlyph that is provided as this parameter.But how could this be? For apparently, no RoundGlyph is created when draw() is called.

You are constructing a RoundGLyph instance. The constructor of RoundGLyph invokes the constructor of the super class - Glyph - which calls the draw() method. Since RoundGLyph overrides Glyph 's draw() method, the Glyph constructor calls RoundGLyph draw() method, which prints the value of radius .

However, since it is called before the RoundGLyph instance is fully initialized (the body of the RoundGLyph constructor has not be executed yet, and even the radius = 1 initialization hasn't been executed yet), the radius variable still holds a default value of 0 . As a result of this behavior of the Java language, it is advised not to call non-final methods in the constructor (since they can be overridden).

Method will be called normally. This time the object pointed to by this is imperfect, but the this pointer is there, so there will be no exception, but it is recommended not to do so because it is dangerous to call the instance method on an imperfect object.

In this case the super constructor is being called that is Glyph constructor is being called. Now the tricky thing which is happening is the call to the draw() method which is overriden in RoundGlyph, hence Glyph makes a call to the overriden version in RoundGlyph, which prints the radius variable, but again a strange observation is that 0 is printed for radius as the child constructor statements were not executed till now, so since it is a primitive, the default value 0 is printed. If it were some object then null would have been printed. Hope this clarifies it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM