Получить доступ

Библиотека объявляет public static final String VERSION = "1.0". В новой версии значение изменили на "2.0" и заменили только jar библиотеки. Что увидит уже скомпилированное приложение?

SeniorОсновы языка
Коротко

Старое "1.0": static final примитив или строка с константным инициализатором — константа времени компиляции, её значение вписано прямо в байт-код потребителя. Без перекомпиляции приложения новое значение не подхватится.

  • Ссылки на класс библиотеки в байт-коде вообще не остаётся
  • Обход: инициализировать через метод — VERSION = String.valueOf("2.0") или читать из ресурса
  • Касается и switch по константам

А ещё Публичные константы в API — часть бинарного контракта

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Правило такое: static final поле примитивного или строкового типа, инициализированное константным выражением, становится константой времени компиляции, и компилятор подставляет её значение прямо в место использования вместо обращения к полю. Ссылки на класс библиотеки в байткоде не остаётся вовсе, поэтому подмена jar ничего не меняет. Это регулярный источник загадочных расхождений между версиями. Если такое поведение нежелательно, константу лишают статуса компиляционной — например, инициализируют вызовом метода. Из того же правила следует, что обращение к константе не вызывает инициализацию класса: статический блок такого класса не выполнится.

Что хотят услышать

  • Механизм подстановки констант.
  • Последствия для библиотек и обход.

Частые ошибки

  • Считать, что подмена jar обновит все значения.
  • Забывать, что обращение к константе не инициализирует класс.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Старое значение "1.0": это константа времени компиляции, её значение вкомпилировано в класс потребителя
  • ✗Новое значение "2.0", как и для любого другого статического поля
  • ✗Будет брошено NoSuchFieldError при обращении
  • ✗Значение будет зависеть от порядка загрузки классов

Что спросят дальше

  • Как объявить поле так, чтобы оно не стало константой времени компиляции?
  • Почему обращение к константе не инициализирует класс?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем