1

This prints out r1 r4 pre b1 b2 r3 r2 hawk

But I don't understand why it prints r3 r2 instead of r2 r3 which seems backwards. If the initialization blocks execute top down, why does it begin with the bottom statement r3 and finish with r2? In the superclass Bird it executes as I would expect with b1 and b2, top to bottom, but in the superclass Raptor, after the constructor runs, control seems to jump to the last statement first and work itself back toward the top. Any ideas?

It's driving me crazy.

class Bird {
   { System.out.print("b1 "); }
   public Bird() 
   { System.out.print("b2 "); 
   }

class Raptor extends Bird {
   static { System.out.print("r1 "); }   
   public Raptor()    
   {System.out.print("r2 "); } // don't these two print backwards?
   {System.out.print("r3 "); }  // ???    
   static { System.out.print("r4 "); }
}   

class Hawk extends Raptor {
   public static void main(String[] args) {
      System.out.print("pre ");
      new Hawk();
      System.out.println("hawk ");
   }
}
Mark
  • 29
  • 1
  • 3

1 Answers1

2

Your class Raptor has one initialization block. It gets copied into the constructor.

public Raptor()    
{System.out.print("r2 "); } // don't these two print backwards?
{System.out.print("r3 "); }  // ???   

Becomes

public Raptor() {
    super();
    System.out.print("r3 "); // <-- initialization block copied in.
    System.out.print("r2 ");
}

which is why you get the output you do.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • Thanks, but why does it pick r3 instead of r2 if r2 comes first? Like it picked b1 first in class Bird? – Mark Nov 26 '15 at 04:13
  • 2
    Because `r2` is in the constructor. That's not an initialization block. – Elliott Frisch Nov 26 '15 at 04:13
  • Thanks. I thought the answer was in that area. So r2 and b2 are simply statements in the constructor, and r3 is inserted ahead of r2, and b1 is likewise inserted ahead of b2. Then, once the constructors run they execute the first b1 (initialization block) and then the statement b2, then r3 (initialization block) and then statement r2. The trick being, while after the constructor, b2 or r2, might look like an initialization block, because they come immediately after the constructor they are in fact merely statements. – Mark Nov 26 '15 at 04:29
  • Well yes, except you literally don't have `r2` in an initialization block. It's already in the constructor. The compiler inserts `super()` and then `r3`. If you comment out the constructor line, you'll have the default constructor. And then you'd get `r2` followed by `r3`. Or if you added `{}` before the block containing `r2` (which is currently the `Raptor` constructor). – Elliott Frisch Nov 26 '15 at 04:31
  • Got it. Thanks so much. That really helps. – Mark Nov 26 '15 at 04:33