20 September 2021

Double-brace Initialization in Java Considered Harmful

...to garbage collectors and kittens.

Well, it seems like only yesterday that I was happily coding away in C#. One of the handy features of that language that we used all the time was object initializers. This feature allowed the programmer to instantiate a new instance of something and also set fields on that something that might otherwise require a separate statement.

public class Cat
{
    // Auto-implemented properties.
    public int Age { get; set; }
    public string Name { get; set; }

    public Cat()
    {
    }

    public Cat(string name)
    {
        this.Name = name;
    }
}

...

Cat cat = new Cat { Age = 10, Name = "Fluffy" };
Cat sameCat = new Cat("Fluffy"){ Age = 10 };

Pretty handy. I was hoping that Java had something similar, and it does. Sort of:

Person person = new Person(){{
    setFirstName("My FirstName");
    setLastName("MyLastName");
}}

This is just a bit wierd though. It's like you're setting up an inner scope in which to execute initialization statments. Well, it turns out that I've been killing kittens, or at least creating more work for the garbage collector. Using this technique tells Java to create anonymous inner classes. Yuck. Lots of other smart people have written about this and the associated pitfalls. Looks like I've got some refactoring to do.