17

for the following code:

class A
{
    public static int X;
    static { X = B.Y + 1;}
}
public class B
{
    public static int Y = A.X + 1;
    static {}
    public static void main(String[] args) {
        System.out.println("X = "+A.X+", Y = "+B.Y);
    }
}

the output is:

X = 1, Y = 2

Why? And How?

P.S: Code snippet taken from JavaCamp.org

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
topgun_ivard
  • 8,376
  • 10
  • 38
  • 45

3 Answers3

27

Here is what happens in chronological order:

  1. Class B contains the main-method so it is loaded by the class loader.

  2. Initialization of B references A, so class A is loaded.

  3. A has a static variable X initialized to B.Y + 1.

    The initialization of B.Y hasn't been executed yet, so B.Y evaluates to 0, and thus 1 is assigned to A.X

  4. Now A has finished loading, and the initialization of B.Y can take place.

    The value of A.X + 1 (1 + 1) is assigned to B.Y.

  5. The values of A.X and B.Y are printed as 1 and 2 respectively.

Further reading:

Java Language Specification, §12.4.1 When Initialization Occurs

Pacerier
  • 86,231
  • 106
  • 366
  • 634
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 2
    Because of the circular initialization dependencies, it goes without saying that this kind of code should be frowned upon. – David R Tribble Jun 20 '11 at 20:32
  • 2
    The key point is to note that static intializers will only be runned once. So if ClassA's static initializer invokes ClassB's static initializer which in turn invokes ClassA's static intializer again, that non-first invocation will be ignored. – Pacerier Sep 08 '14 at 03:34
3

This is only my guess:

  1. Class B is loaded because it contains main which you have requested to be executed.
  2. Class loader discovers that B requires A to operate (it uses A by accessing its static field)
  3. Class B is loaded.
  4. Class A requires class B which happens to be already loaded, but not yet initialized
  5. A carelessly loads B.Y (initialized to 0 by that time by default), since the class looks like loaded (language design flaw?)
  6. A.X = 0 + 1
  7. A is now loaded, class loader can continue to load and initialize B
  8. B.Y = 1 + 1.
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
0

B being public starts to load itself.

Sees A.X = B.Y +1 == which is 0 to start with (default int object value) hence 1;

initializes B = 1 + 1 = 2;

hence the answer.

Nrj
  • 6,723
  • 7
  • 46
  • 58