How to change the value of a static variable?

3

Good, I would like to know how I can change the value of the following constant (To give an example) by a method.

private static double PIVA=0.16;

Edit: I have expressed myself poorly, I am sorry. I misused the word "constant", I wanted to refer to that variable "static". It is defined at the beginning of the class.

Thanks for the answers!

    
asked by Akarin 27.04.2016 в 21:42
source

2 answers

4

What you have there is not a constant, it's just a static variable. To be a constant, it must be defined with the final modifier:

private static final double PIVA=0.16;

Being a constant, its value can not be changed .

Imagine that the field is in a class with the following definition (keeping as you declare it in your example).

class ClaseConCampoEstatico {
    private static double PIVA = 0.16;
    public static final double getPIVA() { return PIVA; }
}

If you want to change its value, you can do it via reflection. You need to know the name of the field you want to modify and then the rest would be simple use of reflection, like this:

//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>);

We will create a method to perform the example:

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());
    }
}

The output of the program:

0.16
1.0

However, if it were a true constant , that is, the field is marked as final , we would see an exception:

class ClaseConCampoEstatico {
    private static final double PIVA = 0.16;
    public static double getPIVA() { return PIVA; }
}
//resto del código...

The output will be:

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

Now, keep in mind that Field#setAccessible will not always work. This is because in some execution environments, there is a SecurityManager that provides security to the application. As part of security, it prevents fields from being modified by reflection to avoid attacks. This happens for example when executing an Applet.

    
answered by 27.04.2016 / 22:01
source
2

Response before the headline was changed. ¿Cómo cambiar el valor de una constante?

In java to define a constant final is used

private static final double PIVA=0.16;

And if you define it as a constant, it does not make sense to be able to change its value dynamically.

    
answered by 27.04.2016 в 22:03