Eclipse и println, похоже, не согласны со значением динамически устанавливаемого частного конечного статического поля

#java #eclipse #static #final #introspection

#java #eclipse #статический #Финал #самоанализ

Вопрос:

Играя с самоанализом, я обнаружил интересную ситуацию, когда:

  • Отображается всплывающая подсказка отладчика Eclipse true
  • println печатает false (обратите внимание на вывод на вкладке консоли):

eclipse

Я пытаюсь установить значение private final static поля, я думаю, я сделал это неправильно?
Что здесь на самом деле происходит?

 import java.lang.reflect.*;

public class Main {

    private final static boolean VAR = false; // I want to dynamically set this to true

    public static void main(String[] args) throws Exception {
        Field field = Main.class.getDeclaredField("VAR");
        field.setAccessible(true);

        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() amp; ~Modifier.FINAL);

        field.set(null, true);
        System.out.println(VAR);
    }
}
  

Комментарии:

1. поскольку VAR является константой, он мог быть встроен.

Ответ №1:

Компилятор «вставляет» static final значение. Если вы посмотрите на байт-код для println , вы увидите что-то вроде:

 iconst_0
invokevirtual java.io.PrintStream.println(boolean) 
  

Поскольку он знает, что значение не изменится, компилятор сгенерировал код, который загружает значение 0 (для false) напрямую, не обращаясь к VAR переменной, поэтому ваше изменение переменной игнорируется.

Из-за встраивания вы не можете полагаться на возможность изменения значения static final переменной с отражением.