Из документации на Field.set
:
Если базовое поле является окончательным, метод выдает IllegalAccessException
, если setAccessible(true)
не удалось для этого поля и это поле нестатично .
Итак, на первый взгляд кажется, что вам не повезло, поскольку File.separatorChar
- это static
. Удивительно, но - это способ обойти это: просто сделайте поле static
больше не final
через отражение.
Я адаптировал это решение от javaspecialist.eu :
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
// remove final modifier from field
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
Я проверил это, и оно работает:
setFinalStatic(File.class.getField("separatorChar"), '#');
System.out.println(File.separatorChar); // prints "#"
Используйте эту технику с особой осторожностью . Помимо разрушительных последствий, на самом деле работает следующее:
setFinalStatic(Boolean.class.getField("FALSE"), true);
System.out.format("Everything is %s", false); // "Everything is true"
Важное обновление : вышеуказанное решение не работает во всех случаях. Если поле становится доступным и читается через «Отражение» до того, как оно будет сброшено, выдается IllegalAccessException
. Он не работает, потому что Reflection API создает внутренние FieldAccessor
объекты, которые кэшируются и используются повторно (см. Реализацию java.lang.reflect.Field # acquFieldAccessor (boolean)).
Пример тестового кода, который не проходит:
Field f = File.class.getField("separatorChar"); f.setAccessible(true); f.get(null);
// call setFinalStatic as before: throws IllegalAccessException