Suponiendo que no SecurityManagerte impide hacer esto, puedes usarlo setAccessiblepara desplazarte privatey restablecer el modificador para deshacerte de él finaly, de hecho, modificar un private static finalcampo.
Aquí hay un ejemplo:
import java.lang.reflect.*;
public class EverythingIsTrue {
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
public static void main(String args[]) throws Exception {
setFinalStatic(Boolean.class.getField("FALSE"), true);
System.out.format("Everything is %s", false); // "Everything is true"
}
}
Asumiendo que no SecurityExceptionse lanza, se imprime el código anterior "Everything is true".
Lo que realmente se hace aquí es lo siguiente:
- Los
booleanvalores primitivos truey falseen mainse autoboxing al tipo de referencia Boolean"constantes" Boolean.TRUEyBoolean.FALSE
- La reflexión se utiliza para cambiar la
public static final Boolean.FALSEreferencia a la Booleanreferencia deBoolean.TRUE
- Como resultado, posteriormente cada vez que un
falsese autoboxed a Boolean.FALSE, se refiere a la misma Booleancomo el referido a porBoolean.TRUE
- Todo lo que era
"false"ahora es"true"
Preguntas relacionadas
Advertencias
Se debe tener mucho cuidado cuando haga algo como esto. Es posible que no funcione porque SecurityManagerpuede estar presente, pero incluso si no lo hace, dependiendo del patrón de uso, puede funcionar o no.
JLS 17.5.3 Modificación posterior de campos finales
En algunos casos, como la deserialización, el sistema necesitará cambiar los finalcampos de un objeto después de la construcción. finallos campos se pueden cambiar a través de la reflexión y otros medios dependientes de la implementación. El único patrón en el que esto tiene una semántica razonable es uno en el que se construye un objeto y luego finalse actualizan los campos del objeto. El objeto no debe hacerse visible para otros subprocesos, ni deben finalleerse los campos, hasta que finalse completen todas las actualizaciones de los campos del objeto. Las congelaciones de un finalcampo se producen tanto al final del constructor en el que finalse establece el campo como inmediatamente después de cada modificación de un finalcampo a través de la reflexión u otro mecanismo especial.
Incluso entonces, hay una serie de complicaciones. Si un finalcampo se inicializa a una constante de tiempo de compilación en la declaración de campo, es finalposible que no se observen cambios en el campo, ya que los usos de ese finalcampo se reemplazan en tiempo de compilación con la constante de tiempo de compilación.
Otro problema es que la especificación permite una optimización agresiva de los finalcampos. Dentro de un hilo, está permitido reordenar las lecturas de un finalcampo con las modificaciones de un campo final que no tienen lugar en el constructor.
Ver también
- JLS 15.28 Expresión constante
- Es poco probable que esta técnica funcione con una primitiva
private static final boolean, porque es inlineable como una constante de tiempo de compilación y, por lo tanto, el valor "nuevo" puede no ser observable
Apéndice: sobre la manipulación bit a bit
Esencialmente,
field.getModifiers() & ~Modifier.FINAL
apaga el bit correspondiente a Modifier.FINALfrom field.getModifiers(). &es el bit a bit y ~el complemento a bit.
Ver también
Recuerda expresiones constantes
¿Aún no puedes resolver esto ?, ¿has caído en la depresión como lo hice yo? ¿Su código se ve así?
public class A {
private final String myVar = "Some Value";
}
Al leer los comentarios sobre esta respuesta, especialmente la de @Pshemo, me recordó que las expresiones constantes se manejan de manera diferente, por lo que será imposible modificarla. Por lo tanto, deberá cambiar su código para que se vea así:
public class A {
private final String myVar;
private A() {
myVar = "Some Value";
}
}
si no eres el dueño de la clase ... te siento!
Para más detalles sobre por qué este comportamiento lee esto ?