What is the order of the Constructors in this Java Code?

后端 未结 5 977
夕颜
夕颜 2021-01-12 18:36

Here is the code, I defined two class named Father and Son, and create them in the main function:

public class Test {
    public static void main(String[] ar         


        
相关标签:
5条回答
  • 2021-01-12 19:02

    Here is what gets called:

    new Son()
    =>  
      Son._init
       =>  first every constructor calls super()
          Father._init
             Object._init
             who()  => is overridden, so prints "son"
             tell(name) => name is private, so cannot be overridden => "father"
       who()  => "son"
       tell(name)  => "son"   
    

    Lessons to learn:

    • private fields and methods are private. Cannot be overridden.
    • Do not call methods from constructors that can be overridden. This can call methods on half-initialized class state (not happening in your case, though).
    0 讨论(0)
  • 2021-01-12 19:12
    1. Let's start with the constructor of Son.

      public Son() {
          super(); // implied
          who();
          tell(name);
      }
      
    2. Father's constructor is called.

      public Father() {
          who();
          tell(name);
      }
      
    3. Because who() is overridden by Son, the Son's version will be called, printing "this is son".

    4. tell() is also overridden but the value passed in is Father.name, printing "this is father".

    5. Finally, the who() and tell(name) calls inside Son's constructor will be made printing "this is son" and "this is son" respectively.

    0 讨论(0)
  • 2021-01-12 19:18

    When you create the Son instance, the parent class' constructor is called (i.e. Father()); here the who() method is called, but it's the overridden version you declared in Son, so here's your first line (where the String is hardcoded inside the method).

    The second line comes from the tell(name) inside Father(), where tell() is overridden but name == "father" as the call comes from within Father's constructor, and name is a private field of class Father.

    Control goes back to Son() constructor, and the last two lines come straightforwardly from the Son class constructor.

    0 讨论(0)
  • 2021-01-12 19:18

    Father() is called before Son(). The superclasses default constructor is implicitely called, we don't need a super() statement here.

    And who() inside the constructor of Father() calls the overriding method.

    0 讨论(0)
  • 2021-01-12 19:22

    The code above is particular Bad Style (TM). ;-)

    What happens is: There is no Father instance, just a Son instance. (It is assignment compatible to Father, however.)

    The Son constructor calls the Father constructor. The latter calls the overridden (!) methods, thus Father.who and Father.tell are never called! The overridden Methods are called before (!) the Son constructor was finished.

    My recommendations:

    1. If you call a method in a constructor, make it final. Or make the whole class final. Or make the called method private at least.
    2. Never override a method called in a constructor.
    3. If you have to violate above recommendations, write extensive comments about why you did so and what you expect to happen. Write a unit test to make sure your assumptions are valid.
    0 讨论(0)
提交回复
热议问题