mvd
mvd

Reputation: 2720

Why can you access static field before it is defined through a method in 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.

Upvotes: 16

Views: 1107

Answers (3)

Renjith
Renjith

Reputation: 3274

This is the generic steps by which class loading happens.

  1. Loading - Load the class to memory
  2. Verification - checks binary representation of a class e is correct
  3. Preparation - create the static fields for the class and initialize those fields to their standard default values.
  4. Initializing - will invoke static initializers and initializers for static fields

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

gaborsch
gaborsch

Reputation: 15758

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.

Upvotes: 3

assylias
assylias

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

Related Questions