Question

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?

Was it helpful?

Solution

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 :)

OTHER TIPS

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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top