Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can you access static field before it is defined through a method in Java?

Tags:

java

I ran into an interesting thing:

static {
    System.out.println(test);     // error cannot reference a field before it is defined
    System.out.println(cheat());  // OK! 
}

private static boolean cheat() {
    return test;
}

private static boolean test = true;

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

The first way is wrong and both your compiler and IDE will tell you it's wrong. In the second case, cheating is OK, but it actually defaults the field test to false. Using Sun JDK 6.

like image 274
mvd Avatar asked Jan 29 '13 16:01

mvd


2 Answers

This is defined in the JLS 8.3.2.3. In particular:

The declaration of a member needs to appear textually before it is used [...] if the usage occurs in a [...] static initializer of C.

When you call cheat() you go around that rule. This is actually the 5th example in the list of the examples of that section.

Note that cheat() will return false in the static initializer block because test has not been initialised yet.

like image 82
assylias Avatar answered Oct 15 '22 01:10

assylias


Because class loading works in this order:

  • Loads Class definition (methods, signatures)
  • Allocates the memory for the static variable references (for test) - does not initialize yet
  • Executes the static initializers (for variables) and the static blocks - in order they are defined

So, by the time you have reachstatic block, you have the method definition ready, but don't have the variable ready. With cheat() you're actually reading an uninitialized value.

like image 29
gaborsch Avatar answered Oct 15 '22 02:10

gaborsch