Инициализация двойной двойки Java работает всегда?
Я знаю, что этот код:
Set<String> set = new HashSet<String>() {{
add("test1");
add("test2");
}};
действительно:
Set<String> set = new HashSet<String>() {
{//initializer
add("test1");
add("test2");
}
};
Блок инициализации выполняется до блока конструктора. В приведенном выше примере add ( "test1" ) вызывается перед выполнением конструктора. Конструктор может инициализировать многие поля экземпляра, чтобы этот класс работал. Мне интересно, зачем вызывать .add() до того, как будет работать конструктор? Есть ли какой-либо случай, который может вызвать проблему?
Ответы
Ответ 1
Есть информация, которую вы оставили, что объясняет это.
Прежде всего, давайте рассмотрим шаги с 3 по 5 процедуры инициализации раздел 15.9.1.)
Поскольку вы не объявили конструктор, используется конструктор по умолчанию. Но до этого конструктор суперкласса HashSet
завершился.
Итак, в итоге конструктор HashSet
завершается до запуска блока инициализации.
Ответ 2
Это предположение неверно:
Блок инициализации выполняется перед блоком конструктора.
Поскольку в этом конкретном случае блок инициализатора является частью блока конструктора.
docs ясно, что
Компилятор Java копирует блоки инициализации в каждый конструктор. Поэтому этот подход может использоваться для совместного использования блока кода между несколькими конструкторами.
Я думаю, вы запутались со статическими инициализаторами.
Ответ 3
Инициализаторы экземпляра выполняются сразу после создания объекта. Вы в основном создаете встроенное расширение HashSet, а затем "сразу после" оно создается, вы добавляете к нему два элемента.
Это шаблон общего использования в макетных объектах для тестирования, например, в JMock, но также имеет другие полезные функции.
Надеюсь, что это поможет.
Ответ 4
Я считаю, что это плохая практика, потому что она создает бессмысленные подклассы, которые могут повлиять на использование памяти и производительность приложения. Во всяком случае, программа правильная, потому что конструктор суперкласса вызывается перед инициализаторами экземпляра. Поэтому, когда запускается ваш инициализатор, конструктор HashSet
запускается, поэтому вызов add
будет работать.