Локальное кэширование констант Java - PullRequest
5 голосов
/ 02 июля 2010

Допустим, у меня есть приложение Java, которое использует (статическую) константу int из библиотеки:

int myval = OutsideLibraryClass.CONSTANT_INT;

Теперь, не перекомпилируя мое приложение, я запускаюэто относительно немного другой версии OutsideLibraryClass, в которой значение CONSTANT_INT отличается.

Будет ли мое приложение видеть новое значение (потому что оно забирает его во время выполнения) или старое (потому что значениескомпилирован в байт-код в моем методе)?Имеет ли какое-то значение, если CONSTANT_INT является окончательным?Есть ли часть спецификации Java, которая говорит об этом?

Ответы [ 4 ]

4 голосов
/ 02 июля 2010

Ссылки на постоянные поля разрешаются во время компиляции в постоянные значения, которые они обозначают. (JLS 13.1)

2 голосов
/ 02 июля 2010

К сожалению, ваш вопрос недостаточно конкретен, чтобы ответить на него, потому что он может измениться или не измениться без перекомпиляции.Вот пример, где значение константы будет изменяться без перекомпиляции.

public class Const {
   public static final int CONSTANT;
   static {
      CONSTANT = 4;
   }
}

class Test
{
   int c = Const.CONSTANT;
}

А вот случай, когда оно не изменится без перекомпиляции

public class Const {
   public static final int CONSTANT = 4;
}

class Test
{
   int c = Const.CONSTANT;
}
1 голос
/ 02 июля 2010

Из спецификации JVM:

Переменная класса - это поле типа класса, объявленное с использованием ключевого слова static (§2.9.1) в объявлении класса или с ключевым словом static или без него в объявлении интерфейса. Переменные класса создаются при загрузке класса или интерфейса (§2.17.2) и инициализируются при создании значениями по умолчанию (§2.5.1). Переменная класса фактически перестает существовать, когда ее класс или интерфейс выгружается (§2.17.8).

Таким образом, когда ClassLoader загружает OutsideLibraryClass, значение инициализируется. Когда вы выполняете оператор присваивания в myVal, значение загружается во время выполнения на основе файла класса OutsideLibraryClass, который был загружен ClassLoader. Поэтому, если вы выключите JVM, поменяете файл jar, содержащий OutsideLibraryClass, и запустите его снова, он получит значение из нового класса.

UPDATE

Приведенное выше утверждение верно, если вы говорите о экземпляре локальной переменной внутри метода. Если ваша переменная myVal объявлена ​​на уровне класса, люди, которые говорят, что она не изменится, верны.

1 голос
/ 02 июля 2010

Нет, это не поднимет новое значение.Это часть языковой спецификации.См этот вопрос .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...