user3907559
user3907559

Reputation: 85

Please explain this behaviour in java

class abc extends TestStart{
     static{
         System.out.println("c");
     }
     {
         System.out.println("f");
     }
     public abc(){
         System.out.println("d");
     }
}

public class TestStart {
     static {
         System.out.println("A");
     }
     {
         System.out.println("z");
     }
     public TestStart(){
         System.out.println("b");
     }

     public static void main(String[] args) {

         TestStart x = new abc();
         TestStart y = new TestStart();             
     }
}

Output-----------> A c z b f d z b

I think output behaviour for this ---->>>>> TestStart x = new abc(); --------should be :-

  1. First static block of both classes will run
  2. Then init block of child class will called because of new abc().But here init of parent class is getting called
  3. Then super() is invoked from new abc() which results in call to parent class constructor.
  4. before parent class constructor ,init block of parent class will execute.
  5. then constructor of parnet class will execute
  6. then constructor of child class will execute.

I should get the following output: A c f z b d z b

This behaviour is largely derived from if there are no init block in parent class and child class. Please explain the output that I have mentioned.

Upvotes: 0

Views: 86

Answers (3)

Mike Nakis
Mike Nakis

Reputation: 61993

You got: A c z b f d z b while you expected: A c f z b d z b

So, you are saying that you expected f to happen before z b.

So, what you are essentially saying is that you expected:

  • an instance initializer of the most derived class (f)

to be invoked before

  • an instance initializer of the base class (z) and
  • the constructor of the base class (b).

Well, that's simply not how things happen. All of the instance initialization of the base class must be completed before instance initialization of the derived class begins, otherwise the derived class would be able to access uninitialized members of the base class.

And all the static initialization stuff (A, c) were red herrings thrown in the question to confuse us.

Upvotes: 2

kajacx
kajacx

Reputation: 12939

First, some naming:

 public class TestStart {
   static { // static initializer
     System.out.println("A");
   }
   { // instance initializer
     System.out.println("z");
   }
   public TestStart() { // constructor
     System.out.println("b");
   }
 }

You are right that static initializers are called first, but the only guarantee you have is that classes static initializer is called before you use that class in any context.

For the instance initializers and constructors, the order of calling is as follows, from first called to last called:

Parent initializer, Parent Constructor, Your Initializer, Your Constructor

If you invoke other constructor from same class using this(), initializer is called once before the all the constructors calls in your class.

Upvotes: 0

VDanyliuk
VDanyliuk

Reputation: 1049

After initialization static blocks and variables in all classes runs initializers of parent. After parent constructor, then initializers of child in child constructor. That's because You can use some parent fields in your child initializers, so they must be initialized before.

Upvotes: 0

Related Questions