user2622016 user2622016 - 3 months ago 17
Java Question

Java: Why no warning when referencing a field before it is defined?

A static field cannot be referenced before it is defined or initialized:

static Integer j = i; /* compile error */
static final Integer i = 5;


However, when it is referenced from an instance initialization block (in an anonymous inner class), not even a warning is generated.

See example:

class StaticInitialization {

static final Object o = new Object() {{
j = i;
}};

static Integer j, k;
static final Integer i = 5;

static final Object o2 = new Object() {{
k = i;
}};
}


The result is:
j == null
,
k == 5
, so clearly we've made a reference, order matters, and no warning or compilation error.

Is this code legal?

Answer

Is this code legal? Probably. I don't think it's the compiler's job to analyze your deliberate side-effects of object instantiation in buggering up static variables.

The limited analysis of 'declare before referencing' from other statics in the same class is really just a helper against the most common boo-boos, not a ironclad guarantee against indirect errors.

I'm really not at all surprised that the the "declare before referencing" analysis is limited in scope to direct access of static variables in other static declarations. This is a simple & compact analysis with minimal complexity & very fast.

Extending it to consider side-effects of object instantiation & method calls, OTOH, would require the 20-1000x greater weight & scope of static program analysis. Static analysis requires access to potentially the entire compiled program code, with constraint-based computation to determine what may possibly happen, and run-times potentially in the minutes.

Given these choices it is fairly easy, in the Java language designer's shoes, to choose simple analysis covering only direct accesses from fields within the same class.