在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Java  網絡安全/ 為什么反射可以修改掉final的值?

為什么反射可以修改掉final的值?

fun initTypeface( name:String, path :String) {
    try {
        val field = Typeface::class.java.getDeclaredField(name)
        field.isAccessible = true
        field.set(null, Typeface.createFromAsset(CoreApp.get().assets, path))
    } catch (e: NoSuchFieldException) {
        e.printStackTrace()
    } catch (e: IllegalAccessException) {
        e.printStackTrace()
    }
}

上面代碼是我的一個用來修改字體的方法。用到了反射修改Typeface類中的字段。

    /** The NORMAL style of the default serif typeface. */
    public static final Typeface SERIF;
    //...
    
       static {
        init();
        // Set up defaults and typefaces exposed in public API
        //..
        SERIF           = create("serif", 0);
        //..
    }

可以看到這個靜態(tài)成員在初始化的時候就被賦值了。但是我的反射方法卻有效果?的確修改掉了字段。

所以我就寫了以下代碼來看反射是否能修改字段。

//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;
    }
}

想通過反射的方法修改TestHelper中的ENTITY字段,但是沒有成功 。沒有被修改掉。而且拋出了異常。

 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)

所以我就很奇怪,為什么一開始的代碼可以修改掉final的值?

——————————
更新,是因為我的代碼被編譯器優(yōu)化了?

回答
編輯回答
使勁操

kotlin不知道,但Java確實不允許修改靜態(tài)常量字段的值,非靜態(tài)的可以。

2017年10月18日 07:39