Рубрики
Без рубрики

Изменение константы в Java во время выполнения (ЧТО?!)

При изучении Java вам сказали, что константы могут быть созданы с помощью ключевого слова final и что t… С пометкой java, новички.

При изучении Java вам сказали, что константы могут быть созданы с помощью ключевого слова final и что значение (или ссылка на объект), которое они содержат, никогда не может быть изменено, иначе они не были бы известны как константы, верно?

Это почти правда. На самом деле, вы можете изменить значение константы с помощью метода, называемого отражением. С помощью отражения вы можете программно получать доступ и изменять информацию о полях, методах и конструкторах загруженных классов во время выполнения.

В этом примере мы меняем частный постоянный ВОЗРАСТ с 50 до 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!");
    }
}

Результирующий результат после компиляции и запуска этого класса выглядит следующим образом:

I'm 15 yo only!

Конечно, изменение константы – совершенно странный вариант использования, хотя я думаю, что это могло бы привлечь ваше внимание к этому (верно?). Тем не менее, отражение – это мощный метод, который помогает разработчикам создавать динамически настраиваемые компоненты. Вы также должны знать, что отражение дорого обходится с точки зрения производительности, поэтому используйте его с умом и только тогда, когда это действительно необходимо.

Последнее, что я хотел бы упомянуть, это то, что этот конкретный пример не будет работать, если константа имеет тип String из-за Java String Constant Pool , но это уже другая история, которую я оставлю на потом…

Оригинал: “https://dev.to/claudiohigashi/changing-a-private-constant-in-java-what-33m9”