2016-12-17 2 views
1

Я взял ссылку из Change private static final field using Java reflection и написал ниже кода, чтобы обновить тип String, статическое конечное значение поля:Поданное Значение Обновления с Java Reflection

У меня есть один класс, который содержит Constant, как показано ниже:

public final class Constants { 

    public static final String ACCEPTED = "A"; 
} 

Я пытался обновить это значение с помощью Java Reflection, как показано ниже:

Field field = Constants.class.getDeclaredField("ACCEPTED"); 
    field.setAccessible(true); 

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

    String newValue = "B"; 
    field.set(null, newValue); 

После обновления значения, используя выше код, который я тестировал, как показано ниже:

String myUpdatedValue = Constants.ACCEPTED; 

Вот когда я осмотрены Constants.ACCEPTED значение в настоящее время было показано «В», но когда я осмотрены myUpdatedValue, она показывает, как «А». Не могу понять причину. Даже когда я передаю это значение другому методу в качестве параметра, по вызову метода это «B», но внутри вызываемого метода это «A».

ответ

1

Цитирую the documentation:

Примечание: Если примитивный тип или строка определяется как константа, а значение известно во время компиляции, компилятор заменяет постоянное имя всюду в коде с его значение. Это называется константой времени компиляции. Если значение константы во внешнем мире изменяется (например, если принято, что pi на самом деле должно быть 3.975), вам нужно будет перекомпилировать любые классы, которые используют эту константу, чтобы получить текущее значение.

В вашей ситуации Constants.ACCEPTED - такая константа времени компиляции. Поэтому, когда ваш код скомпилирован, все ссылки на Constants.ACCEPTED фактически заменены буквами "A". Ваш код управляет своим значением во время выполнения, но это уже слишком поздно.

+0

Большое спасибо за ваше объяснение, полностью понятное, поэтому любой способ добиться этого разрешен во время выполнения? Помимо создания метода и возврата этой строки из этого метода. – proudandhonour

+1

@proudandhonour Я предполагаю, что вы могли бы использовать некоторую форму манипуляции с байтовым кодом, например [javassist] (https://jboss-javassist.github.io/javassist/), но я бы очень внимательно это рассмотрел перед запуском и внедрением , Это много хлопот, и часто довольно хрупкий, поэтому вам нужно быть на 100% уверенным, что вы действительно ** хотите это сделать. – Mureinik

Смежные вопросы