Библиотека объявляет public static final String VERSION = "1.0". В новой версии значение изменили на "2.0" и заменили только jar библиотеки. Что увидит уже скомпилированное приложение?
Старое "1.0": static final примитив или строка с константным инициализатором — константа времени компиляции, её значение вписано прямо в байт-код потребителя. Без перекомпиляции приложения новое значение не подхватится.
- Ссылки на класс библиотеки в байт-коде вообще не остаётся
- Обход: инициализировать через метод — VERSION = String.valueOf("2.0") или читать из ресурса
- Касается и switch по константам
А ещё Публичные константы в API — часть бинарного контракта
Подробно
Правило такое: static final поле примитивного или строкового типа, инициализированное константным выражением, становится константой времени компиляции, и компилятор подставляет её значение прямо в место использования вместо обращения к полю. Ссылки на класс библиотеки в байткоде не остаётся вовсе, поэтому подмена jar ничего не меняет. Это регулярный источник загадочных расхождений между версиями. Если такое поведение нежелательно, константу лишают статуса компиляционной — например, инициализируют вызовом метода. Из того же правила следует, что обращение к константе не вызывает инициализацию класса: статический блок такого класса не выполнится.
Что хотят услышать
- Механизм подстановки констант.
- Последствия для библиотек и обход.
Частые ошибки
- Считать, что подмена jar обновит все значения.
- Забывать, что обращение к константе не инициализирует класс.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Новое значение "2.0", как и для любого другого статического поля
- ✗Будет брошено NoSuchFieldError при обращении
- ✓Старое "1.0": константа вкомпилирована в класс потребителя
- ✗Значение будет зависеть от того, какой класс загрузчик успел загрузить первым
Что спросят дальше
- Как объявить поле так, чтобы оно не стало константой времени компиляции?
- Почему обращение к константе не инициализирует класс?
Разбор темы
- final, static и порядок инициализации
Семантика final (и почему это не immutable), static-члены, порядок инициализации класса и объекта, константы и ловушки.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.