In this tutorial we will check, why is double brace initialization an anti pattern.
Lets look at this code:
List languages = new ArrayList() {{ add("C"); add("C++"); add("Java"); }};
At first glance, the code looks good – it initializes the list in one line with values. It is correct code, but used incorrectly may lead to unexpected behavior, so lets check the possible consequences.
Two pairs of braces aren’t special construction in Java: First pair of braces creates an anonymous inner class that extends ArrayList, while the second pair define an initialization block in which instance is initialized (the block is called from the constructor). So it is just a normal combination of anonymous class and initialization block.
But this construction may lead to several problems:
- Every time the list is created the new anonymous class is created – imagine this code in method that is called thousands or millions of time – it can be a serious overhead to classloader.
- The anonymous class will hold hidden reference to the class in which it was created. Imagine that list after creation will be returned form method and reused in further processing.
This will also have negative impact on application performance – JVM won’t be able to garbage collect the enclosing class, this may even lead to memory leaks.
There can also be problems with serialization of such list – Java will want to serialize the outer class together with the list.
Summarizing, please be aware of these side effects next time you will want to initialize objects using this construction. Maybe the readability of the code isn’t worth the negative impact on the performance of this solution. Especially, when there are other ways of initializing list, which are much faster and more elegant:
In Java 8:
List languages = Stream.of("C", "C++", "Java").collect(Collectors.toList());
In Java 9:
List languages = List.of("C", "C++", "Java");