3

When going through the JLS 8.3.2.3 I wasn't able to understand the following code.

class Z {
static { i = j + 2; }
static int i, j;
static { j = 4; }
}

The code is resulting in the error Cannot reference a field before it is defined

But if I change the code to

class Z {
static { i = 2; }
static int i, j;
static { j = 4; }
}

The code is getting compiled. But in both the cases the variable definition is after the initialization block. What is the mystery behind this?

Dungeon Hunter
  • 19,827
  • 13
  • 59
  • 82
  • 1
    They are declarations, known before any code is ran... this is like asking why can I call a method from a method that's defined above the method to be called – Esailija Jan 21 '13 at 07:28
  • 1
    @Esailija: Whats the difference between `i` and `j`. Why error for `j` only? It will be good if you provide more information. – Ajinkya Jan 21 '13 at 07:31

3 Answers3

8

You can assign to a value earlier than its declaration - you just can't read it. So this fails too:

static { System.out.println(j + 2); }
static int j;

Whereas this is fine:

static { j = 5; }
static int j;

One of the four conditions in section 8.3.2.3 for an invalid usage is:

  • The usage is not on the left hand side of an assignment.

(The double-negatives in that section are making my head hurt, but I think it relevant!)

To be honest, that part of the spec is one of the worst I've seen - it's really unclear. But the upshot is that you can assign but not read :)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

Actually,Its an compiler basics,

the assignment statements are executed from right to left.

e.g.i=2;

it means 2 is assigned to i,and 2 is constant hence no need to declare it

In the other hand if we write

i=j+2;

it will compile j first and then assign it to the i hence it causes the error because j is not defined yet.

dd619
  • 5,910
  • 8
  • 35
  • 60
0

In i = j + 2; you use the variable j that is initialize in a different static block.

You should put everything togheter, in only one static block, the j initialization and the expression to get the code compiled. This code works:

public class Z {

    static int i, j;
    static { j = 4; 
            i = j + 2; }

}

Davide

Panciz
  • 2,183
  • 2
  • 30
  • 54