Android меняет личное статическое конечное поле с помощью Java Reflection?

Я хочу установить "NO_CACHE" как newValue. Вот мой код:

static void setFinalStatic(Object newValue) throws Exception
{
    Field field = CacheManager.class.getDeclaredField("NO_CACHE");
    field.setAccessible(true);
    Field modifiersField=Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field,field.getModifiers() & ~Modifier.FINAL);
    field.set(null, newValue);
}

Но запуск этого кода на Android вызывает следующую ошибку:

java.lang.NoSuchFieldException: modifiers

Я нахожу, что modifiers является полем класса Field в Java, но это не поле в классе Field на Android.

Это код класса Java Field:

http://www.docjar.com/html/api/java/lang/reflect/Field.java.html

Это код класса Android Field:

http://www.oschina.net/code/explore/android-2.2-froyo/java/lang/reflect/Field.java

Вышеприведенный код на Java может работать, но он не работает на платформе Android.

Как это исправить?

Ответ 1

Android на самом деле не использует исходный код JDK. Это что-то очень похожее, но не то же самое.

В Java модификаторы имеют тип java.lang.reflection.Field, но в Android такого типа нет. Android реализовал систему, которая использует целое число и имя поля для проверки его модификаторов, вызывая собственный метод.

Я думаю, что поле private static final будет иметь slot -1, а частное поле будет иметь значение 3. Если вы хотите изменить поле private static final, просто измените slot на 3 перед установкой значения.

Field booleanField = Boolean.class.getField("FALSE");
booleanField.setAccessible(true);

Field slotField = Field.class.getDeclaredField("slot");
slotField.setAccessible(true);
slotField.set(booleanField, 3);

booleanField.set(Boolean.FALSE, true);

Ответ 2

Из предоставленных вами ссылок выглядит, что поле modifiers фактически является членом класса AccessibleObject.

Попробуйте использовать

Field modifiersField = AccessibleObject.class.getDeclaredField("modifiers");

Просто догадаться. Caveat Lector

Кроме того, он помечается как окончательный. Вероятно, вы не должны этого делать.