Reputation: 2720
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.
Upvotes: 16
Views: 1107
Reputation: 3274
This is the generic steps by which class loading happens.
After preparation, your test will be false.Then before you assign static variable to true, your static block will execute.That is why you are getting false.
Try making your static variable final.In that case,you will be getting true.This is because your compiler itself will embed the value in bytecode(since the field is final) as part of optimisation
Upvotes: 1
Reputation: 15758
Because class loading works in this order:
test
) - does not initialize yetstatic
initializers (for variables) and the static
blocks - in order they are definedSo, 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.
Upvotes: 3
Reputation: 328598
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.
Upvotes: 11