Consider the below scenario:
Code:1
public class StaticDemo {
static{
b=5;
System.out.println("Static B:"+b);/*Compilation error:"Cannot reference a field before it is defined"*/
}
static int b;
static{
System.out.println("B:"+b);
}
public static void main(String[] args) {
}
}
Commenting the code as below, there are no errors and following output has been displayed.
Code:2
public class StaticDemo {
static{
b=5;
//System.out.println("Static B:"+b);
}
static int b;
static{
System.out.println("B:"+b);
}
public static void main(String[] args) {
}
}
Output-
B:5
If the execution is based on the order in which static variables or blocks have been written.
why compilation error is not thrown for the initialization (b=5
)
as shown in Code:2.
And also please explain why error is been thrown for Code:1, if Code:2 is true?
From the Java Language Specification §8.3.2.3
The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
- The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.
- The usage is not on the left hand side of an assignment.
- The usage is via a simple name.
- C is the innermost class or interface enclosing the usage.
It is a compile-time error if any of the four requirements above are not met.
[...]
The restrictions above are designed to catch, at compile time, circular or otherwise malformed initializations
In other words, it's OK to write to a field that is declared later in the class, but not to read from it.
There are more detailed examples of this in the example box immediately following the section I have quoted.