Обложка канала

Библиотека Java разработчика

9291 @BookJava

Библиотека Java разработчика. Книги по программированию на Java.

Библиотека Java разработчика

4 года назад
Открыть в
Как изменить значение приватного финального поля? Стоит сразу сказать, это очень плохая практика. Такое изменение грубо нарушает принципы сокрытия данных, и потенциально ломает инвариантность состояния объекта. Для этого трюка необходимо прибегнуть к использованию Reflection API. Сначала получим дескриптор поля – экземпляр класса Field. У объекта метакласса Class<X> интересующего нас класса вызовем метод getDeclaredField(). Просто getField() не сработает, потому что он работает только с публичными полями. Параметром передается строка с именем поля. Полученного экземпляра Field уже достаточно для доступа к изменяемым приватным полям. Перед обращением требуется сделать его доступным, вызвав setAccessible(true). Сам доступ осуществляется методами get*() и set*(). Так как Field представляет дескриптор поля класса, без привязки к конкретному экземпляру класса, экземпляр передается параметром в методы доступа. Для статического поля передается null. Чтобы побороть неизменяемость финального поля, нужно снять его модификатор final. Все модификаторы поля хранятся в поле modifiers дескриптора. То есть, нужно также с помощью рефлекшена сделать доступным и обновить поле уже объекта Field. Поле modifiers хранит модификаторы в виде битовой маски. Для изменения придется прибегнуть к битовым операторам. Полный код установки значения 42 в поле myField объекта myObject выглядит так: Field field = myObject.class.getDeclaredField( "myField" ); field.setAccessible( true ); Field modifiersField = Field.class.getDeclaredField( "modifiers" ); modifiersField.setAccessible( true ); modifiersField.setInt( field, field.getModifiers() & ~Modifier.FINAL ); field.setInt(myObject, 42); #Классы