Michael
Michael

Reputation: 4461

Unpredictable behaviour of an initializer block

public class Ex14 {
    static String strDef = "At the point of definition";
    static String strBlock;
    { strBlock = "In a block";}

    public static void main (String [] args){       
        System.out.println(Ex14.strDef);
        System.out.println(Ex14.strBlock);
        Ex14 test = new Ex14();
        System.out.println(test.strBlock);
        System.out.println(Ex14.strBlock);
    }

}

Result:

$ java Ex14
At the point of definition
null
In a block
In a block

If I switch the block with the commented one, both statements are printed. In other words, I just

Well, I can't catch what is going on here.

Questions:

  1. Inside the initializer block the variable is non-static. If it is not anyhow mixed with that static declaration, why the compiler didn't even warn me?

  2. When an instance was created, strBlock is not null anymore. I can't catch why?

  3. Anyway, I can't understand anything here. Please, could you clarify it somehow?

Upvotes: 0

Views: 53

Answers (1)

Andy Turner
Andy Turner

Reputation: 140514

  1. Inside the initializer block the variable is non-static. If it is not anyhow mixed with that static declaration, why the compiler didn't even warn me?

No, the variable is still static. You're just assigning a new value to the static variable.

  1. When an instance was created, strBlock is not null anymore. I can't catch why?

Instance initializers are inlined into the constructor, in between an (implicit or explicit) call to super(...) and the rest of the body. What you have here is equivalent to:

public class Ex14 {
    static String strDef = "At the point of definition";
    static String strBlock;

    public Ex14() {  // Default constructor.
      super(); // Implicit super constructor invocation.

      // Inlined instance initializer.
      Ex14.strBlock = "In a block";

      // Rest of the constructor body (there is none for a default ctor).
    }

    public static void main (String [] args){ 
      // ...
    }
 }

So, before you create an instance, the Ex14.strBlock = "In a block"; statement hasn't executed, so its value is null; after you create an instance (and hence execute the constructor), Ex14.strBlock has been reassigned.

Upvotes: 2

Related Questions