DEV Community

loading...

Changing a constant in Java at runtime (WHAT?!)

claudiohigashi profile image Claudio Higashi ・2 min read

When learning Java, you were told that constants can be created by using the final keyword and that the value (or the object reference) they hold can never be changed, otherwise, they wouldn't be known as constants, right?

That's almost true. In fact, you can change the value of a constant with the use of a technique called Reflection. With reflection, you are able to programmatically access and change information about fields, methods, and constructors of loaded classes at runtime.

In this example, we are changing the private constant AGE from 50 to 15:

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class ModifyConstant {
    public static void main(String[] args) throws Exception {
        OldPerson fakeYoungPerson = new OldPerson();
        changePrivateConstant(fakeYoungPerson, "AGE", 15);
        fakeYoungPerson.sayYourAge();
    }

    public static void changePrivateConstant(Object instance, String constantName, Object newValue) throws Exception {
        // gets the Field object which represents the constant
        Field field = instance.getClass().getDeclaredField(constantName);

        // need this because AGE is 'private'
        field.setAccessible(true);

        Field modifiers = field.getClass().getDeclaredField("modifiers");

        // need this because modifiers of any Field are 'private'
        modifiers.setAccessible(true);

        // this kind of removes the 'final' keyword.
        // it actually turns off the bit representing the 'final' modifier
        modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);

        // and now we are able to set the new value to the constant
        field.set(instance, newValue);
    }

}

class OldPerson {
    private static final Integer AGE = 50;

    public void sayYourAge() {
        System.out.println("I'm " + AGE + " yo only!");
    }
}

The resulting output after compiling and running this class is:

I'm 15 yo only!

Of course that changing a constant is a completely weird use case, although I think that might have caught your attention to this (right?). Nevertheless, reflection is a powerful technique that helps developers to create dynamically configurable components. You also need to be aware that reflection costs a lot in terms of performance, so use it wisely and only when really needed.

The last thing that I would like to mention, is that this particular example wouldn't work if the constant is of type String because of the Java String Constant Pool, but this is a different story which I will leave for later...

Discussion (0)

pic
Editor guide