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