I am working with forward references in Java and wondering why Java allows forward reference with either ClassName
(in static variable) or with this
reference in case of instance variable? What is the background process that is taking place at the level of JVM? For instance:
Static Forward Reference-
class StaticForwardReferences {
static {
sf1 = 10; // (1)
int b = sf1 = 20; // (2)
int c = StaticForwardReferences.sf1; // (3) Works fine
// Above statement allows the allocation of value of 'sf1'
// to variable 'c' just because it is accessed with class name
// instead of direct name
// whereas below statement throws illegal forward reference
// error at compile time
System.out.println(sf1); // (4) Illegal forward reference
}
static int sf1 = sf2 = 30;
static int sf2;
public static void main(String[] args) {}
}
Is there any kind of temporary storage where the values get stored when we do a forward reference by assigning the variables before their declaration as done in (1) and (2) steps above, if we print the value of variable c
, it shows the value from the most recent assignment did to sf1
.
Non-static Forward Reference-
class NonStaticForwardReferences {
{
nsf1 = 10;
System.out.println(this.nsf1); // 10
nsf1 = sf1;
// System.out.println(nsf1); Illegal forward reference
int b = nsf1 = 20;
int c = this.nsf1;
System.out.println(c); // 20
// why variable 'c' is initialized to 20 when used with 'this' reference
// instead of showing illegal forward reference, how it works in the background?
}
int nsf1 = nsf2 = 30;
int nsf2;
static int sf1 = 5;
public static void main(String[] args) {}
}
Please put some light on the background process that is taking place behind the scenes for the above two cases. Thanks in advance! :)
Java requires that the declaration of a field must occur before its usage in any initializer expression if the field is used on the right-hand side of an assignment in the initializer expression. This essentially means that the declaration of a field must occur before the value of the field is read in an initializer expression.
When making forward references using simple names, code in a static initializer block is also subject to the declaration-before-reading rule discussed above.
As in an instance initializer expression, the keywords "this" and "super" can be used to refer to the current object in an instance initializer block.