//FinalTest
class FinalTest {
public static void main(String[] args) {
try {
Field field = TestHelper.class.getDeclaredField("ENTITY");
field.setAccessible(true);
Entity entity = new Entity("reflection name");
field.set(null, entity);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(TestHelper.getENTITY().name);
}
static class Entity {
public String name;
public Entity(String name) {
this.name = name;
}
}
}
//..TestHelper
class TestHelper {
private static final FinalTest.Entity ENTITY;
static {
ENTITY = new FinalTest.Entity("init name");
}
public static FinalTest.Entity getENTITY() {
return ENTITY;
}
}
tried to modify the ENTITY
field in TestHelper
by reflection, but failed. It hasn"t been modified. And threw an exception.
Can not set static final com.company.finaltest.Entity field
java.lang.IllegalAccessException: Can not set static final com.company.finaltest.Entity field com.company.finaltest.TestHelper.ENTITY to com.company.finaltest.Entity
at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:76)
at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:80)
at sun.reflect.UnsafeQualifiedStaticObjectFieldAccessorImpl.set(UnsafeQualifiedStaticObjectFieldAccessorImpl.java:77)
at java.lang.reflect.Field.set(Field.java:764)
at com.company.finaltest.FinalTest.main(FinalTest.java:13)
so I wonder why the initial code can change the value of final?
-
is it because my code has been optimized by the compiler?