Зачем создается статический объект и какую задачу он решает
Что проверяют
Понимаете ли вы, что такое статическое поле на уровне JVM: когда оно создаётся, где живёт и сколько у него копий. Следом обычно спрашивают про потокобезопасность и про то, почему статику не любят в тестах.
Как отвечать
Уточните термин: «статический объект» это обычный объект, на который ссылается static-поле. Поле принадлежит классу, а не экземпляру, поэтому копия одна на класс в рамках одного загрузчика классов.
Создаётся он при инициализации класса, то есть при первом активном использовании (создание экземпляра, вызов статического метода, чтение неконстантного статического поля), а не при старте программы. JVM выполняет инициализацию один раз и потокобезопасно, на этом держится идиома Holder для ленивого синглтона без synchronized.
Задачи:
- константы и тяжёлые неизменяемые объекты: скомпилированный
Pattern,DateTimeFormatter, таблицы соответствий. Создаются один раз, а не на каждый вызов; - логгер:
private static final Logger log = LoggerFactory.getLogger(Foo.class); - общий кэш или реестр: с оговоркой про потоки и вытеснение;
- синглтон: хотя в Spring эту роль выполняют бины со скоупом singleton, и статика там не нужна.
Хранение: PermGen убрали в Java 8, метаданные классов лежат в Metaspace, а статические поля в HotSpot находятся в куче вместе с объектом Class. Статическое поле служит корнем для GC, поэтому объект живёт, пока класс не выгружен.
Цена: глобальное изменяемое состояние, скрытые зависимости, трудная подмена в тестах.
Где спотыкаются
Кладут в статику изменяемый непотокобезопасный объект. Классика: static SimpleDateFormat, который из нескольких потоков выдаёт мусорные даты. Замена: неизменяемый DateTimeFormatter.
Делают статическую коллекцию кэшем без ограничения размера. Она растёт до OutOfMemoryError, а при передеплое в сервере приложений ещё и удерживает старый загрузчик классов.
Путают static и final. Первое про принадлежность классу, второе про запрет переприсвоить ссылку, одно не подразумевает другое.