1. Overview
In this quick tutorial, weβll show how double braces can be used for creating and initializing objects in a single Java expression.
Weβll also look at why this technique can be considered an anti-pattern.
2. Standard Approach
Normally we initialize and populate a set of countries as follows:
@Test
public void whenInitializeSetWithoutDoubleBraces_containsElements() {
Set<String> countries = new HashSet<String>();
countries.add("India");
countries.add("USSR");
countries.add("USA");
assertTrue(countries.contains("India"));
}
As can be seen from above example, we are doing the following:
- Create an instance of HashSet
- Add countries to the HashSet
- Finally, we assert whether the country is present in the HashSet
3. Using Double Brace
However, we can actually combine the creation and initialization in a single statement; this is where we make use of double braces:
@Test
public void whenInitializeSetWithDoubleBraces_containsElements() {
Set<String> countries = new HashSet<String>() {
{
add("India");
add("USSR");
add("USA");
}
};
assertTrue(countries.contains("India"));
}
As can be seen from above example, we are:
- Creating an anonymous inner class which extends HashSet
- Providing an instance initialization block which invokes the add method and adds the country name to the HashSet
- Finally, we can assert whether the country is present in the HashSet
4. Advantages of Using Double Braces
There are some simple advantages of using double braces:
- Fewer lines of code compared to the native way of creation and initialisation
- The code is more readable
- Creation initialization is done in the same expression
5. Disadvantages of Using Double Braces
Disadvantages of using double braces are:
- Obscure, not widely known way to do the initialization
- It creates an extra class every time we use it
- Doesnβt support the use of the βdiamond operatorβ β a feature introduced in Java 7
- Doesnβt work if the class we are trying to extend is marked final
- Holds a hidden reference to the enclosing instance, which may cause memory leaks
Itβs due to these disadvantages that double brace initialization is considered as an anti-pattern.
6. Alternatives
6.1. Stream Factory Methods
Instead, we can make good use of the new Java 8 Stream API to initialize our 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 Collections Factory Methods
Also, Java 9 will bring a set of useful factory methods that will make the following possible:
List<String> list = List.of("India", "USSR", "USA");
Set<String> set = Set.of("India", "USSR", "USA");
You can read more about this in this article.
7. Conclusion
In this concise tutorial, we discussed the usage of double braces along with its advantages and disadvantages.
