Что такое инициализация двойными фигурными скобками в Java?
Что такое синтаксис инициализации двойными фигурными скобками ({{ ... }}) в Java?
Переведено автоматически
Ответ 1
Инициализация двойными фигурными скобками создает анонимный класс, производный от указанного класса (внешние фигурные скобки), и предоставляет блок инициализатора внутри этого класса (внутренние фигурные скобки). например
newArrayList<Integer>() {{ add(1); add(2); }};
Обратите внимание, что результатом использования этой инициализации двойными фигурными скобками является создание анонимных внутренних классов. Созданный класс имеет неявный this указатель на окружающий внешний класс. Хотя обычно это не проблема, в некоторых обстоятельствах это может вызвать проблемы, например, при сериализации или сборе мусора, и об этом стоит знать.
Ответ 2
Каждый раз, когда кто-то использует инициализацию двойными фигурными скобками, погибает котенок.
Это довольно большие накладные расходы для вашего загрузчика классов - впустую! Конечно, это не займет много времени на инициализацию, если вы сделаете это один раз. Но если вы сделаете это 20 000 раз в своем корпоративном приложении... вся эта куча памяти только ради небольшого количества "синтаксического сахара"?
2. Вы потенциально создаете утечку памяти!
Если вы возьмете приведенный выше код и вернете эту карту из метода, вызывающие этот метод могут ничего не подозревая удерживать очень тяжелые ресурсы, которые не могут быть собраны в мусор. Рассмотрим следующий пример.:
publicclassReallyHeavyObject {
// Just to illustrate... privateint[] tonsOfValues; private Resource[] tonsOfResources;
// This method almost does nothing public Map quickHarmlessMethod() { Mapsource=newHashMap(){{ put("firstName", "John"); put("lastName", "Smith"); put("organizations", newHashMap(){{ put("0", newHashMap(){{ put("id", "1234"); }}); put("abc", newHashMap(){{ put("id", "5678"); }}); }}); }};
return source; } }
Возвращаемое значение Map теперь будет содержать ссылку на заключенный экземпляр ReallyHeavyObject. Вы, вероятно, не хотите рисковать этим:
3. Вы можете притвориться, что в Java есть литералы отображения
Чтобы ответить на ваш актуальный вопрос, люди использовали этот синтаксис, чтобы притвориться, что в Java есть что-то вроде литералов map , похожих на существующие литералы array:
Первая фигурная скобка создает новый анонимный внутренний класс. Эти внутренние классы способны получать доступ к поведению своего родительского класса. Итак, в нашем случае мы фактически создаем подкласс класса HashSet, поэтому этот внутренний класс способен использовать метод put() .
И Второй набор фигурных скобок - это не что иное, как инициализаторы экземпляра. Если вы помните основные концепции Java, то вы можете легко связать блоки инициализатора экземпляра со статическими инициализаторами благодаря схожей структуре, подобной фигурным скобкам. Единственное отличие заключается в том, что статический инициализатор добавляется с помощью ключевого слова static и запускается только один раз; независимо от того, сколько объектов вы создаете.