Java Reference
In-Depth Information
17.5.3. Subsequent Modification of
final
Fields
In some cases, such as deserialization, the system will need to change the
final
fields
of an object after construction.
final
fields can be changed via reflection and other
implementation-dependent means. The only pattern in which this has reasonable semantics
is one in which an object is constructed and then the
final
fields of the object are updated.
The object should not be made visible to other threads, nor should the
final
fields be read,
until all updates to the
final
fields of the object are complete. Freezes of a
final
field occur
both at the end of the constructor in which the
final
field is set, and immediately after each
modification of a
final
field via reflection or other special mechanism.
Even then, there are a number of complications. If a
final
field is initialized to a compile-
be observed, since uses of that
final
field are replaced at compile time with the value of the
constant expression.
Another problem is that the specification allows aggressive optimization of
final
fields.
Within a thread, it is permissible to reorder reads of a
final
field with those modifications of
a
final
field that do not take place in the constructor.
Example 17.5.3-1. Aggressive Optimization of
final
Fields
class A {
final int x;
A() {
x = 1;
}
int f() {
return d(this,this);
}
int d(A a1, A a2) {
int i = a1.x;
g(a1);
int j = a2.x;
return j - i;
}
static void g(A a) {
// uses reflection to change a.x to 2
}
}