In the below code while accessing a static variable with class name it doesn't throw a forward reference error but accessing it without class name does.
Why this doesn't happen when accessing with class name?
class Test{
static {
System.out.println(a); // shows error
a = 99; // and this line too doesn't give error
System.out.println(Test.a); // this line doesn't
}
static int a = 10;
static{
System.out.println(a);
}
}
The rules for forward reference is defined in JLS §8.3.3:
Use of class variables whose declarations appear textually after the use is sometimes restricted, even though these class variables are in scope (§6.3). Specifically, it is a compile-time error if all of the following are true:
The declaration of a class variable in a class or interface C appears textually after a use of the class variable;
The use is a simple name in either a class variable initializer of C or a static initializer of C;
The use is not on the left hand side of an assignment;
C is the innermost class or interface enclosing the use.
So, basically your first Sysout()
, satisfies all the above 4 conditions, and hence it's a compile time error.
In the 2nd Sysout()
, you're accessing a
using it's qualified name, rather than simple name, which as per the above rules is allowed.
Now, the reason for this would be, when you access Test.a
, the compiler is sure that Test
class has been loaded and all static
fields have been initialized, so it can access the field a
. But while accessing a
on simple name, the compiler isn't sure that initializer for a
has already run or not, since it might still be in process of loading the class.
Consider the following process of loading of class:
static
variables declared in it. At this point, the variable a
has got its memory allocated (declaration done)static
initializers run in the order of occurrence.
Sysout(a);
. a
hasn't been initialized yet, so you can't access it. (error)a = 99
. Here you're actually initializing the variable a
. Perfectly fine.Sysout(Test.a)
- reasoning for this is already posted above. Compiler knows Test
is already loaded.static int a = 10
is executed. It re-initializes a
to 10
. Remember, declaration part is already taken care of in first step.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With