Double Brace Initialization in Java

Java, a versatile and widely-used programming language, offers various idioms and patterns to make developers' lives easier. One such idiom that gained popularity but is now considered an anti-pattern is the Double Brace Initialization. In this article, we delve deep into this idiom, understanding its pros, cons, and better alternatives.

graph TD A[Double Brace Initialization] B[Pros: Conciseness, Simultaneous Creation] C[Cons: Obscurity, Additional Overhead, Memory Leaks] D[Alternatives: Copy Constructors, Java 8's Stream API] A --> B A --> C A --> D

Understanding Double Brace Initialization

Double Brace Initialization is an idiom in Java that allows for the initialization of collections, such as lists, sets, and maps, at the time of their declaration. This idiom became popular due to the absence of a standard way to simultaneously create and initialize collections in Java.

For instance, initializing an unmodifiable list with a few elements traditionally requires multiple lines of code:

Java
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);

However, with Double Brace Initialization, the same can be achieved in a single line:

Java
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
    add(2);
    add(3);
    add(5);
}});

Similarly, HashMaps can be initialized with values using this idiom:

Java
Map<Integer, String> intToString = new HashMap<Integer, String>() {{
    put(1, "one");
    put(2, "two");
    put(3, "three");
}};

Advantages and Disadvantages

Pros:

  1. Conciseness: Reduces the number of lines of code.
  2. Simultaneous Creation and Initialization: Allows for both in a single expression.

Cons:

  1. Obscurity: Relies on the instance initializer construct of anonymous classes, making it less intuitive.
  2. Additional Overhead: Every usage results in the creation of an extra class.
  3. Potential Memory Leaks: Holds a hidden reference to the enclosing instance.

Given these drawbacks, Double Brace Initialization is now viewed as an anti-pattern in Java.

Superior Alternatives

Java offers better alternatives to achieve the same results without the pitfalls of Double Brace Initialization.

Using Copy Constructors:

One can create and initialize an ArrayList with values in a single line using the copy constructor:

Java
List<Integer> list = Collections.unmodifiableList(
    new ArrayList<>(Arrays.asList(2, 3, 5))
);

Leveraging Java 8’s Stream API:

For those using Java 8, the Stream API provides another alternative:

Java
List<String> list = Collections.unmodifiableList(
    Stream.of("abc", "bcd", "cde").collect(toList())
);

For sets:

Java
Set<String> set = Collections.unmodifiableSet(
    Stream.of("abc", "bcd", "cde").collect(toSet())
);

Conclusion

While Double Brace Initialization offers a concise way to initialize collections, its disadvantages make it less suitable for production code. Developers are advised to opt for alternatives like copy constructors or the Stream API, which are more efficient and intuitive.

Author