1. Обзор
В этом кратком руководстве мы покажем, как двойные скобки можно использовать для создания и инициализации объектов в одном выражении Java .
Мы также рассмотрим, почему эту технику можно считать анти-паттерном.
2. Стандартный Подход
Обычно мы инициализируем и заполняем набор стран следующим образом:
@Test public void whenInitializeSetWithoutDoubleBraces_containsElements() { Setcountries = new HashSet (); countries.add("India"); countries.add("USSR"); countries.add("USA"); assertTrue(countries.contains("India")); }
Как видно из приведенного выше примера, мы делаем следующее:
- Создайте экземпляр HashSet
- Добавление стран в хэш-набор
- Наконец, мы утверждаем, присутствует ли страна в HashSet
3. Использование Двойной Скобки
Однако на самом деле мы можем объединить создание и инициализацию в одном операторе; именно здесь мы используем двойные скобки:
@Test public void whenInitializeSetWithDoubleBraces_containsElements() { Setcountries = new HashSet () { { add("India"); add("USSR"); add("USA"); } }; assertTrue(countries.contains("India")); }
Как видно из приведенного выше примера, мы:
- Создание анонимного внутреннего класса, который расширяет HashSet
- Предоставление блока инициализации экземпляра, который вызывает метод add и добавляет имя страны в HashSet
- Наконец, мы можем утверждать, присутствует ли страна в HashSet
4. Преимущества использования двойных брекетов
Есть несколько простых преимуществ использования двойных скобок:
- Меньше строк кода по сравнению с собственным способом создания и инициализации
- Код более читабелен
- Инициализация создания выполняется в том же выражении
5. Недостатки использования двойных брекетов
Недостатками использования двойных брекетов являются:
- Неясный, не широко известный способ инициализации
- Он создает дополнительный класс каждый раз, когда мы его используем
- Не поддерживает использование “алмазного оператора” – функции, введенной в Java 7
- Не работает, если класс, который мы пытаемся расширить, помечен final
- Содержит скрытую ссылку на заключающий экземпляр, что может привести к утечке памяти
Именно из-за этих недостатков инициализация двойной скобки рассматривается как анти-шаблон.
6. Альтернативы
6.1. Методы потоковой фабрики
Вместо этого мы можем хорошо использовать новый потоковый API Java 8 для инициализации нашего Set :
@Test public void whenInitializeUnmodifiableSetWithDoubleBrace_containsElements() { Setcountries = Stream.of("India", "USSR", "USA") .collect(collectingAndThen(toSet(), Collections::unmodifiableSet)); assertTrue(countries.contains("India")); }
6.2. Методы фабрики коллекций Java 9
Кроме того, Java 9 принесет набор полезных заводских методов, которые сделают возможным следующее:
Listlist = List.of("India", "USSR", "USA"); Set set = Set.of("India", "USSR", "USA");
Подробнее об этом вы можете прочитать в этой статье.
7. Заключение
В этом кратком руководстве мы обсудили использование двойных скобок, а также их преимущества и недостатки.
Реализацию этих примеров можно найти в проекте GitHub – это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.