Предполагая, что ничто SecurityManager не мешает вам сделать это, вы можете использовать setAccessible для обхода private и сброса модификатора, чтобы избавиться от final, и фактически изменить private static final поле.
В результате, впоследствии, когда a false автоматически добавляется в Boolean.FALSE, оно ссылается на то же Boolean, что и то, на которое ссылается Boolean.TRUE
Есть примеры работы с Integerкэшем, изменения a String и т. Д
Предостережения
Всякий раз, когда вы делаете что-то подобное, следует соблюдать крайнюю осторожность. Это может не сработать, потому что SecurityManager может присутствовать, но даже если этого не произойдет, в зависимости от шаблона использования, это может сработать, а может и не сработать.
В некоторых случаях, таких как десериализация, системе потребуется изменить final поля объекта после построения. final поля могут быть изменены с помощью отражения и других средств, зависящих от реализации. Единственный шаблон, в котором это имеет разумную семантику, - это тот, в котором создается объект, а затем final поля объекта обновляются. Объект не должен быть виден другим потокам, а final поля не должны считываться, пока не будут завершены все обновления final полей объекта. Зависания final поля происходят как в конце конструктора, в котором задано final поле, так и сразу после каждой модификации final поля с помощью отражения или другого специального механизма.
Даже в этом случае существует ряд сложностей. Если final поле инициализировано константой времени компиляции в объявлении поля, изменения в final поле могут не наблюдаться, поскольку использование этого final поля заменяется во время компиляции константой времени компиляции.
Другая проблема заключается в том, что спецификация допускает агрессивную оптимизацию final полей. В потоке допустимо изменять порядок чтения final поля с теми модификациями конечного поля, которые не выполняются в конструкторе.
Маловероятно, что этот метод работает с примитивом private static final boolean, потому что он может быть встроен как константа времени компиляции, и, следовательно, "новое" значение может быть не наблюдаемым
Приложение: О побитовых манипуляциях
По сути,
field.getModifiers() & ~Modifier.FINAL
отключает бит, соответствующий Modifier.FINAL from field.getModifiers(). & является побитовым-и, и ~ является побитовым дополнением.
Читая комментарии к этому ответу, особенно от @Pshemo, я вспомнил, что постоянные выражения обрабатываются по-разному, поэтому изменить его будет невозможно. Следовательно, вам нужно будет изменить свой код, чтобы он выглядел следующим образом:
publicclassA { privatefinal String myVar;
privateA() { myVar = "Some Value"; } }
если вы не являетесь владельцем класса... Я чувствую вас!
Для получения более подробной информации о причинах такого поведения прочтите это?
Ответ 2
Если значение, присвоенное static final boolean полю, известно во время компиляции, это константа. Поля примитивного или String типа могут быть константами времени компиляции. Константа будет встроена в любой код, который ссылается на поле. Поскольку поле фактически не считывается во время выполнения, его изменение не будет иметь никакого эффекта.
Если поле является постоянной переменной (§ 4.12.4), то удаление ключевого слова final или изменение его значения не нарушит совместимость с ранее существующими двоичными файлами, поскольку они не будут запускаться, но они не увидят никакого нового значения для использования поля, если они не будут перекомпилированы. Это верно, даже если само использование не является постоянным выражением во время компиляции (§15.28)
Небольшое любопытство из спецификации языка Java, глава 17, раздел 17.5.4 "Поля, защищенные от записи":
Обычно поле, которое является конечным и статическим, не может быть изменено. Однако, System.in System.out и System.err являются статическими конечными полями, которые по устаревшим причинам должны быть разрешены для изменения методами System.setIn, System.setOut и System.setErr. Мы называем эти поля защищенными от записи, чтобы отличать их от обычных конечных полей.
Также я исправил проблему, с override которой, похоже, не было в предыдущих решениях. Однако используйте это очень осторожно, только когда нет другого хорошего решения.