The following does not compile, giving an 'illegal forward reference' message:
class StaticInitialisation {
static
{
System.out.println("Test string is: " + testString);
}
private static String testString;
public static void main(String args[]) {
new StaticInitialisation();
}
}
However, the following does compile:
class InstanceInitialisation1 {
{
System.out.println("Test string is: " + this.testString);
}
private String testString;
public static void main(String args[]) {
new InstanceInitialisation1();
}
}
But the following does not compile, giving an 'illegal forward reference' message:
class InstanceInitialisation2 {
private String testString1;
{
testString1 = testString2;
}
private String testString2;
public static void main(String args[]) {
new InstanceInitialisation2();
}
}
Why do StaticInitialisation and InstanceInitialisation2 not compile, while InstanceInitialisation1 does?
Simple reason - it's too expensive or impossible to analyze and forbid all forward references. e.g.
The spec settles on forbidding some simple cases indicative of common programmer mistakes.
See also Recursive initializer works when I add "this"?
Here what we have to understand is that in 2nd code snippet You are using block and this keyword.
Lets look at these two example, I guess this will make you clear.
Output:
And
output :
So you can say the sequence are like this.
Static variable will be created but not be initialized.
Static initialization will be executed according to the given sequence.
By sequence I mean appearance in the code.
I guess this steps answer your two not working example
StaticInitialisation
andInstanceInitialisation2
But in case your second working example
InstanceInitialisation1
by usingthis
key word you are actually helping compiler to overlook the textual hierarchy. Same thing happen in case ofstatic
when I callInstanceAndSataticInit.testStringStatic
in my first example InstanceAndSataticInitThis is covered by section 8.3.3 of the JLS:
In your second case, the use isn't a simple name - you've got
this
explicitly. That means it doesn't comply with the second bullet in the second list quoted above, so there's no error.If you change it to:
... then it won't compile.
Or in the opposite direction, you can change the code in the static initializer block to:
Odd, but that's the way it goes.