Почему java требует сделать поле константой, тогда как оно уже является константой?

Значение аннотации @EnableRedisHttpSession инициализируется значением константы SESSION_TIME_TO_LIVE:

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = SessionConfig.SESSION_TIME_TO_LIVE)
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {

    public static final Integer SESSION_TIME_TO_LIVE = 600;

    ...
}

При попытке запуска приложения возникает ошибка: java: element value must be a constant expression. Так как поле SESSION_TIME_TO_LIVE имеет иммутабельный тип Integer, а само оно отмечено final, то его вполне можно считать константой. Так почему возникает ошибка?

Любопытно, что ошибка исчезает, если заменить Integer на int. Интересно, что также проблем не возникает с использованием String, хотя это не примитив:

@RestController
@RequestMapping(AdminReportController.REST_URL)
@AllArgsConstructor
public class AdminReportController {

    protected static final String REST_URL = "/reports";

    ...

Почему такое происходит?


Ответы (1 шт):

Автор решения: Spatz

Integer - это класс-обертка примитивного типа int, и не может быть константным выражением, т.к. создание экземпляра класса происходит во время выполнения программы, а константное выражение должно быть вычислено компилятором ещё до запуска программы.

По поводу класса String могу сказать, что, как и в большинстве других языков, этот класс стоит особняком по одной простой причине: основная часть констант в любой программе - это строковые литералы. Было-бы расточительством копировать их в динамическую память при запуске программы ради одного лишь объектно-ориентированного подхода. Объекты строковых литералов в Java являются фактически ссылками на область памяти в DATA-сегменте и компилятор может работать с ними, как с примитивными данными.

→ Ссылка