public class Main {
static int x = Main.y;
// static int x = y; //Not allowed; y is not defined
static int y = x;
public static void main(String[] args) {
System.out.println(x);//prints 0
}
}
How come I am allowed to use y trough the class, but not directly?
When is y defined?
The precise rules governing forward reference to class variables are described in the section §8.3.2.3 of the JLS:
8.3.2.3 Restrictions on the use of Fields during Initialization
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 (respectivelystatic
) 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.
A compile-time error occurs if any of the four requirements above are not met.
This means that a compile-time error results from the test program:
class Test { int i = j; // compile-time error: incorrect forward reference int j = 1; }
whereas the following example compiles without error:
class Test { Test() { k = 2; } int j = 1; int i = j; int k; }
even though the constructor (§8.8) for Test refers to the field k that is declared three lines later.
These restrictions are designed to catch, at compile time, circular or otherwise malformed initializations. Thus, both:
class Z { static int i = j + 2; static int j = 4; }
and:
class Z { static { i = j + 2; } static int i, j; static { j = 4; } }
result in compile-time errors. Accesses by methods are not checked in this way, so:
class Z { static int peek() { return j; } static int i = peek(); static int j = 1; } class Test { public static void main(String[] args) { System.out.println(Z.i); } }
produces the output:
0
because the variable initializer for i uses the class method peek to access the value of the variable j before j has been initialized by its variable initializer, at which point it still has its default value (§4.12.5).
I would assume that by using the class, the compiler would defer looking for the variable until the class was complete, so it finds y, but if you just define it like the comment it is not yet defined so it fails
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