Java reflection to set static final field fails after previous reflection

不羁的心 提交于 2019-12-06 02:55:38

If you want the modifier hack (don't forget it is a total hack) to work, you need to change the modifiers private field before the first time you access the field.

So, before you do f.getInt(null);, you need to do:

mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);

The reason is that only one internal FieldAccessor object is created for each field of a class (*), no matter how many different actual java.lang.reflect.Field objects you have. And the check for the final modifier is done once when it constructs the FieldAccessor implementation in the UnsafeFieldAccessorFactory.

When it is determined you can't access final static fields (because, the setAccessible override doesn't works but non-static final fields, but not for static final fields), it will keep failing for every subsequent reflection, even through a different Field object, because it keeps using the same FieldAccessor.

(*) barring synchronization issues; as the source code for Field mentions in a comment:

// NOTE that there is no synchronization used here. It is correct (though not efficient) to generate more than one FieldAccessor for a given Field.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!