While debugging memory leaks, I often need to modify field values via reflection. I came across a great Stack Overflow answer worth documenting.
Can We Modify private static final Fields?
Assuming no SecurityManager is preventing it, you can use setAccessible to bypass private, then remove the final modifier to actually modify a private static final field.
Example
| |
If no SecurityException is thrown, this prints “Everything is true”.
How It Works
- The primitive
booleanvaluestrueandfalseinmainare autoboxed toBoolean.TRUEandBoolean.FALSE - Reflection changes
public static final Boolean.FALSEto refer to the same object asBoolean.TRUE - Consequently,
falseautoboxes toBoolean.TRUE - Everything that was “false” now reads as “true”
Bitwise Manipulation
| |
field.getModifiers()gets the modifier bitmask~Modifier.FINALinverts the FINAL bit- The AND operation clears the FINAL bit
Caveats
- This behavior depends on the SecurityManager configuration
- JLS 17.5.3 states: final fields can be changed via reflection, but this only has reasonable semantics when an object is constructed, its final fields are updated, and the object is not made visible to other threads until updates are complete
- If a final field is initialized to a compile-time constant, changes may not be observable because the constant is inlined at compile time
- The specification allows aggressive optimization of final fields, including reordering reads with modifications not happening in the constructor
See also JLS 15.28 Constant Expression: this technique is unlikely to work with a private static final boolean primitive because it is inlined as a compile-time constant.