The error message that the compiler provides is quite helpful in determining the cause. In this case, it says, "illegal forward reference" at that line. So that means you are trying to use a variable before it has been textually declared. This section from JLS should be helpful in understanding why.
Tim McGuire wrote:The compiler will run through all that static stuff outside of methods first and do it sequentially.
But that doesn't explain why there is no compiler error when you delete line 5 even though x is still referenced on line 4 before it is declared on line 7
you are right, it does not explain why. Reading the link to the JLS:
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.
A compile-time error occurs if any of the four requirements above are not met.
the statement x = 2 does meets all the above conditions. System.out.println(x) must violate the fourth condition. this usage is enclosed in another class.