Why can reflection change the value of final?

//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?

Mar.06,2021

kotlin does not know, but Java does not allow you to modify the value of static constant fields, which are non-static.

Menu