2

In my understanding of static members of a class it will be executed depending on the sequence they were written on the class for example:

class GelInk{

    static{
        System.out.println("First Static");
    }

    {
        System.out.println("Initialization block don't mind me");
    }

    static{
        System.out.println("Second Static");
    }

}

//Results to
First Static
Second Static
Initialization block don't mind me

but when I tried this code:

class Ink{

        static{
            a=printStaticMessages(0);
        }
        static int a = printStaticMessages(1);

        Ink(){
            System.out.println(a);
        }

        static int printStaticMessages(int a){
            System.out.println("This is a static messages method " + a);
            return a;
        }
    }

it compiles fine, I expected a compilation error or something because the static variable a is being used by the static block before it was being declared. The above code results to the following when the object of the class was created:

This is a static messages method 0
This is a static messages method 1
1
anathema
  • 947
  • 2
  • 15
  • 27
  • Note that the parameter `a` in `printStaticMessages` is shadowing the `static` field of the same name. – Sotirios Delimanolis Jul 13 '15 at 15:12
  • Yes I am aware of the shadowing of the local variable to the static member of the class, but my question is how come that it compiles and runs without any problems since the static block is already using the static variable a before declaring it. @SotiriosDelimanolis – anathema Jul 13 '15 at 15:14
  • The language allows it, if it's an assignment expression. You could not have done `System.out.println(a);`. – Sotirios Delimanolis Jul 13 '15 at 15:15
  • The order of *declaration* of member fields doesn't amount to much. Consider `class A { A() { o = this; } Object o; }`. – Samuel Edwin Ward Jul 13 '15 at 15:16
  • @SamuelEdwinWard It does in most cases. In this case it doesn't because of [JLS8.3.3](https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.3.3): `The use is not on the left hand side of an assignment;` – biziclop Jul 13 '15 at 15:17
  • @anathema FYI, this is also possible with instance variables. – Chetan Kinger Jul 13 '15 at 15:17
  • 1
    @SotiriosDelimanolis Done, thanks. – biziclop Jul 13 '15 at 15:19
  • 2
    I was going to post an answer, but comments will have to suffice. Here's some relevant JLS sections: [4.12.3](http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.3), [12.3.2](http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.3.2), [4.12.5](http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.5), and [8.7](http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.7). Essentially, variables are defined during class "preparation" which is a step before "initialization", at which time both `static` blocks and assignments are executed. – dimo414 Jul 13 '15 at 15:19
  • lot many answer same question http://stackoverflow.com/questions/2007666/in-what-order-do-static-initializer-blocks-in-java-run?lq=1 http://stackoverflow.com/questions/2007666/in-what-order-do-static-initializer-blocks-in-java-run?lq=1 http://stackoverflow.com/questions/12448465/in-what-order-are-static-blocks-and-static-variables-in-a-class-executed – Ankur Anand Jul 13 '15 at 15:20
  • @dimo414 There is an additional restriction though that prevents static initialisers from "forward referencing" static fields defined later in the source code, even though they are in scope and their default value has been set. Not in this case though, because the forward reference is an assignment. – biziclop Jul 13 '15 at 15:22
  • @biziclop thanks, I should have included 8.3 in my list. – dimo414 Jul 13 '15 at 15:29

0 Answers0