Search code examples
javastaticfinal

in what order are static blocks and static variables in a class executed?


Possible Duplicate:
Java static class initialization

Why is the string variable updated in the initialization block and not the integer(even though the block is written first)

class NewClass
{
    static 
    {
       System.out.println(NewClass.string+" "+NewClass.integer);
    }

    final static String string="static";
    final static Integer integer=1;

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

My output is

static null

P.S:Also noticed that string variable initialization happens before the block only when i insert the final modifier. why is that?why not for integer as well?I have declared it as final static too


Solution

  • From section 12.4.2 of the JLS, snipped appropriately:

    The procedure for initializing C is then as follows:

    • Then, initialize the final class variables and fields of interfaces whose values are compile-time constant expressions (§8.3.2.1, §9.3.1, §13.4.9, §15.28).

    • Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.

    So for non-compile-time-constants, it's not a case of "all variables" and then "all static initializers" or vice versa - it's all of them together, in textual order. So if you had:

    static int x = method("x");
    
    static {
        System.out.println("init 1");
    }
    
    static int y = method("y");
    
    static {
        System.out.println("init 2");
    }
    
    static int method(String name) {
        System.out.println(name);
        return 0;
    }
    

    Then the output would be:

    x
    init 1
    y
    init 2
    

    Even making x or y final wouldn't affect this here, as they still wouldn't be compile-time constants.

    P.S:Also noticed that string variable initialization happens before the block only when i insert the final modifier.

    At that point, it's a compile-time constant, and any uses of it basically inlined. Additionally, the variable value is assigned before the rest of the initializers, as above.

    Section 15.28 of the JLS defines compile-time constants - it includes all primitive values and String, but not the wrapper types such as Integer.