Try to predict the behavior of the execution or compilation
of the following code!
public class Main
{ final int a; final int b;
Main(){ this.a = 0; Main.this.b = 0; }
public static void Main( final java.lang.String[] args )
{ new Main(); }}
(I made this observation while programming something else
using Oracle JDK 7, but I have not read the JLS about it yet.)
It is weird indeed that the compilation should yield the following error:
Main.java:3: error: cannot assign a value to final variable b
Main(){ this.a = 0; Main.this.b = 0; }
^
1 error
In section 15.11.1., /Field Access Using a Primary/
(<
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.11>),
the JLS states:
"At run time, the result of the field access expression is computed as
follows:
(...)
If the field is not static:
(...)
If the field is not final, or is a blank final and the field access
occurs in a constructor, then the result is a variable, namely the named
member field in type T found in the object referenced by the value of
the Primary."
So it should be all right.
Then again, perhaps the following plays a role; the same section also
states:
"At run time, the result of the field access expression is computed as
follows: (assuming that the program is correct with respect to definite
assignment analysis, i.e. every blank final variable is definitely
assigned before access)" (note the bit in parentheses).
Section 16, /Definite Assignment/
(<
http://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html>), states:
"Each local variable (§14.4) and every blank final field (§4.12.4,
§8.3.1.2) must have a definitely assigned value when any access of its
value occurs.
(...)
Such an assignment is defined to occur if and only if either the simple
name of the variable (or, for a field, its simple name qualified by
this) occurs on the left hand side of an assignment operator."
Note how assignment with a qualified this isn't mentioned.
Seems like a bit of a grey area to me.