This answer is more than exhaustive on the topic.
JLS 17.5.3 Subsequent Modification of Final Fields
Even then, there are a number of complications. If a final field is
initialized to a compile-time constant in the field declaration,
changes to the final field may not be observed, since uses of that
final field are replaced at compile time with the compile-time
constant.
But, if you read the paragraph above very carefully, you may find a way around here (set the private final
field in the constructor instead of in the field definition):
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) throws Exception {
WithPrivateFinalField pf = new WithPrivateFinalField();
System.out.println(pf);
Field f = pf.getClass().getDeclaredField("s");
f.setAccessible(true);
System.out.println("f.get(pf): " + f.get(pf));
f.set(pf, "No, you’re not!");
System.out.println(pf);
System.out.println("f.get(pf): " + f.get(pf));
}
private class WithPrivateFinalField {
private final String s;
public WithPrivateFinalField() {
this.s = "I’m totally safe";
}
public String toString() {
return "s = " + s;
}
}
}
The output is then as follows:
s = I’m totally safe
f.get(pf): I’m totally safe
s = No, you’re not!
f.get(pf): No, you’re not!
Hope this helps a bit.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…