Java Double Brace Initialization

Java double brace initialization is defined as creating and initializing the objects in a single step, normally done in multiple steps. They are done using double curly braces.

1. Create and Initialize without Double Braces

In Java, every time we have to use a collection (List, Set or Map) in our code, we have to perform the following actions-

  • Declare a variable for a temporary collection
  • Create a new empty collection and store a reference to it in the variable
  • Put things into the collection
  • Pass the collection to the method

In the following example, we are creating a Set of Strings and adding 3 string values to the set:

Set<String> params = new HashSet<>();


2. Using Double Brace Initialization

Let us see another easy way of doing it using double braces. The syntax to use the double brace feature is obscure and not easily understood at the first sight:

Set<String> params = new HashSet<String>() {

3. How does Double Brace Initialization Work?

Let us understand how this works. The first brace creates a new anonymous inner class. These inner classes are capable of accessing the behavior of their parent class. So, in our case, we are actually creating a subclass of HashSet class, so this inner class is capable of using add() method.

And the second set of braces are nothing but instance initializers. If you remind core java concepts, you can easily associate instance initializer blocks with static initializers due to a similar brace-like structure. The only difference is that a static initializer is added with the static keyword and is run only once, no matter how many objects you create.

4. Alternate Approaches

4.1. Java 9 Stream Factory Methods

Java 9 has brought a lot of factory methods that can be used to create and initialize the Java collections in a single statement. It can be an alternative and preferred approach if you are using Java 9 or later. It eliminates the necessity of double brace initialization.

The following is an example of creating the instances of Map, List and Set using the double braces.

List<String> names = List.of("lokesh", "rohit", "alex");
Set<String> names = Set.of("Lokesh", "Amit", "John");
Map<String, String> names = Map.ofEntries(
                        Map.entry("1", "Lokesh"),
                        Map.entry("2", "Amit"),
                        Map.entry("3", "Brian"));

4.2. Java 8 Stream Collectors

Since Java 8, you can find similar use cases in form of Streams API. It provides a number of useful collectors that can collect the Stream elements into a variety of Collection types.

Set<String> names = Stream.of("one", "two", "three").collect(collectingAndThen(toSet(),Collections::unmodifiableSet ));

5. Limitations

  • Classes initialized with double braces are basically inner classes. So we can create them for all other classes until they are not final.
  • Such classes should not be used where equals() method is not explicitly modified to use them because mostly equals() method checks for class equality also.
  • You should always keep in mind that initializers are run before constructors (but not before super-class constructors).
  • The instance of the anonymous class that you have created contains a synthetic reference to the enclosing object. If you serialize the collection you will also serialize everything in the outer class.

6. Conclusion

In this Java tutorial, we learned to use the double brace initialization and differentiate it from the standard initialization that creates a lot of boilerplate code. We learned the limitations of the double braces and how to use the alternate approaches to have the same result but with more robust code.

Happy Learning !!


Notify of
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.