For a full description , see Section 8.3.3 Java Language Specifications: " Direct Links During Field Initialization "
A direct reference (referring to a variable that has not yet been declared at this point) is only an error if everything is correct:
An instance variable declaration in a class or C interface appears after using an instance variable text
Usage is a simple name in a C instance variable initializer or C instance initializer;
Use is not on the left side of the assignment;
C is the innermost class or interface that spans usage.
See bold text: "use is a simple name." A simple name is the name of a variable without further qualification. In your code, b is a simple name, but this.b is not.
But why?
The reason is because the italic text in the example in JLS reads:
"The limitations given above are intended to catch at compile time, circular or otherwise distorted initializations."
In other words, they allow this.b because they believe that a qualified link makes it more likely that you carefully thought about what you are doing, but just using b probably means you made a mistake.
This is the rationale for Java designers. As far as this is true in practice, as far as I know, I have never been investigated.
Initialization order
To expand on above, citing Dukeling's comment on the issue, using the qualified this.b link this.b most likely not give you the desired results.
I limit this discussion to instance variables because the OP refers only to them. The order in which instance variables are assigned is described in JLS 12.5 Creating Instances of a New Class . It must be taken into account that the superclass constructors are created first, and the initialization code (assignments and initialization blocks) is executed in textual order.
So, given
int a = this.b; int b = 2;
as a result, we get a equal to zero (the value of b at the time of execution of a initializer) and b is 2.
Even stranger results can be achieved if the superclass constructor calls a method that is overridden in a subclass, and this method assigns the value b .
So, in general, it is recommended to think about the compiler and either change the order of your fields, or fix the main problem in the case of cyclic initializations.
If you need to use this.b to get around the compiler error, then you are probably writing code that will be very difficult for the person to maintain after you.