So, execute the following code:
import java.lang.reflect.Field; class Test { public Test() { doIt(); } public void doIt() {} } public class TestReflection extends Test { private final String name = "Immutable"; private String n = "n"; public TestReflection() { } public void doIt() { System.out.println("1 = " + name); System.out.println(n); System.out.println("-----"); } public static void main(String[] args) throws Exception { TestReflection abc = new TestReflection(); Class c1 = Class.forName("TestReflection"); Field field2 = c1.getDeclaredField("name"); field2.setAccessible(true); System.out.println("2 = " + abc.name); field2.set(abc, "Mutable"); System.out.println("3 = " + abc.name); } } Output: 1 = Immutable null ----- 2 = Immutable 3 = Immutable
And the following version of the code:
import java.lang.reflect.Field; class Test { public Test() { doIt(); } public void doIt() {} } public class TestReflection extends Test { private final String name; private String n = "n"; public TestReflection() { name = "Immutable"; } public void doIt() { System.out.println("1 = " + name); System.out.println(n); System.out.println("-----"); } public static void main(String[] args) throws Exception { TestReflection abc = new TestReflection(); Class c1 = Class.forName("TestReflection"); Field field2 = c1.getDeclaredField("name"); field2.setAccessible(true); System.out.println("2 = " + abc.name); field2.set(abc, "Mutable"); System.out.println("3 = " + abc.name); } } Output: 1 = null null ----- 2 = Immutable 3 = Mutable
The answer to this behaviour can be found in JLS (http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html), section 17.5.3,
"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. "
No comments:
Post a Comment