//obtenemos el campo que queremos modificar
//el método getDeclaredField busca en todos los campos de la clase
//sin importar su visibilidad (private, default, protected, public)
Field field = ClaseConCampoEstatico.class.getDeclaredField("PIVA");
//se define que el campo es accesible
field.setAccessible(true);
//se cambia el valor del campo
//el primer parámetro consiste del objeto sobre el cual
//se va a cambiar el valor del campo
//como se trata de un campo estático, el valor no depende de
//una variable en particular por lo que solo usamos null
//el segundo parámetro consiste del nuevo valor que tendrá el campo
field.setDouble(null, <nuevo valor>);
我们将创建一个方法来执行示例:
class ClaseConCampoEstatico {
private static double PIVA = 0.16;
public static double getPIVA() { return PIVA; }
}
public class Main {
public static void cambiaValor(double nuevoValor) {
try {
Field field = ClaseConCampoEstatico.class.getDeclaredField("PIVA");
field.setAccessible(true);
field.setDouble(null, nuevoValor);
} catch (Exception e) {
System.out.println("No se pudo cambiar el valor :(");
e.printStackTrace(System.out);
}
}
public static void main(String[] args) {
System.out.println(ClaseConCampoEstatico.getPIVA());
cambiaValor(1.0);
System.out.println(ClaseConCampoEstatico.getPIVA());
}
}
程序的输出:
0.16
1.0
但是,如果它是一个真正的常量,即该字段被标记为final,我们会看到一个异常:
class ClaseConCampoEstatico {
private static final double PIVA = 0.16;
public static double getPIVA() { return PIVA; }
}
//resto del código...
输出将是:
0.16
No se pudo cambiar el valor :(
java.lang.IllegalAccessException: Can not set static final double field ClaseConCampoEstatico.PIVA to (double)1.0
at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:76)
at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:112)
at sun.reflect.UnsafeQualifiedStaticDoubleFieldAccessorImpl.setDouble(UnsafeQualifiedStaticDoubleFieldAccessorImpl.java:159)
at java.lang.reflect.Field.setDouble(Field.java:1060)
at Main.cambiaValor(Main.java:13)
at Main.main(Main.java:22)
0.16
你所拥有的不是一个常数,它只是一个静态变量。要成为常量,必须使用修饰符定义
final
:作为一个常数,它的值不能改变。
想象一下,该字段位于具有以下定义的类中(在您的示例中声明它时保留它)。
如果你想改变它的值,你可以通过反射来实现。您需要知道要修改的字段的名称,然后剩下的就是简单地使用反射,如下所示:
我们将创建一个方法来执行示例:
程序的输出:
但是,如果它是一个真正的常量,即该字段被标记为
final
,我们会看到一个异常:输出将是:
现在请记住,它
Field#setAccessible
并不总是有效。这是因为在某些运行时环境中,有一个SecurityManager提供应用程序安全性。作为安全的一部分,它防止字段被反射修改以防止攻击。例如,在执行 Applet 时会发生这种情况。标题更改前的响应。
¿Cómo cambiar el valor de una constante?
在
java
定义一个常量时,使用final
如果你将它定义为一个常量,那么动态地改变它的值是没有意义的。