Change private static final field using Java reflection

前端 未结 12 2337
天涯浪人
天涯浪人 2020-11-21 05:52

I have a class with a private static final field that, unfortunately, I need to change it at run-time.

Using reflection I get this error: java.lan

12条回答
  •  醉酒成梦
    2020-11-21 06:13

    Many of the answers here are useful, but I've found none of them to work on Android, in particular. I'm even a pretty hefty user of Reflect by joor, and neither it nor apache's FieldUtils - both mentioned here in some of the answers, do the trick.

    Problem with Android

    The fundamental reason why this is so is because on Android there's no modifiers field in the Field class, which renders any suggestion involving this code (as in the marked answer), useless:

    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    

    In fact, to quote from FieldUtils.removeFinalModifier():

    // Do all JREs implement Field with a private ivar called "modifiers"?
    final Field modifiersField = Field.class.getDeclaredField("modifiers");
    

    So, the answer is no...

    Solution

    Pretty easy - instead of modifiers, the field name is accessFlags. This does the trick:

    Field accessFlagsField = Field.class.getDeclaredField("accessFlags");
    accessFlagsField.setAccessible(true);
    accessFlagsField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    

    Side-note #1: this can work regardless of whether the field is static in the class, or not.

    Side-note #2: Seeing that the field itself could be private, it's recommended to also enable access over the field itself, using field.setAccessible(true) (in addition to accessFlagsField.setAccessible(true).

提交回复
热议问题