or

Double Brace Initialization

Java doesn’t have a really nice way to initialize the collections. Because of this creating some constant collections, passing them to a method, or using them while unit-testing is kinda way too hard. For instance; you just need a 3 items in your list, but Java expects you to define in the following way:

List<String> threeItems = new ArrayList<String>();

threeItems.add("ITEM 1");
threeItems.add("ITEM 2");
threeItems.add("ITEM 3");

someMethodRequiresThreeItems(threeItems);

Well, this is one of common misunderstanding about Java actually. Java has double brace initialization which allows you to initialize any of your objects (this only works for non-final classes) in double brace syntax. The following code does exact same thing with the one above:

someMethodRequiresThreeItems(
  new ArrayList<String>() {{
     add("ITEM 1");
     add("ITEM 2");
     add("ITEM 3");
  }}
);

So what happened? The first brace creates a new AnonymousInnerClass, and the second tells that this is an instance initializer block which runs when the anonymous inner class is instantiated.

This type of initializer block is called an instance initializer, because it is declared within the instance scope of the class. The initializer block can use any methods, fields and final variables available within the scope. The one thing you need to know is the fact that initializers run before constructors.

And this only works only for non-final classes. Because it needs to create an anonymous subclass, and obviously you cannot do this with the final classes. And nice thing about this type of initialization is that you are not limited to collections, it can be used to initialize any kind of object. Please check following:

 add(new JPanel() {{
    setLayout(...);
    setBorder(...);
    ...
 }});

One little note here is that if you have a non-trivial equals method implemented for your class, you wouldn’t wanna use double brace initialization. Because it sometimes cause some trouble on equality.

Anway, I’ll try to give more tips like this. Hope you like it!

Edit: I closed comments for this post, since I received so many pointless comments. Everybody is quite welcome to put their pointless opinions about anything, but not here! Sorry for inconvenience.



7 Responses

  1. Stefan

    It’s a cool trick – but I wouldn’t use it unless someone proves me that the impact on memory usage and VM performance isn’t too bad (you’re creating a new subclass when you actually want a new instance). BTW what’s so bad about Arrays.asList(”ITEM 1″,”ITEM 2″,”ITEM 3″)?

    May 28, 2009, 1:01 PM
  2. Isa Goksu

    Yeah that’s true. I wouldn’t use it too under a high performance requirement. This is just a nice trick for mostly unit-tests (at least I’m using for that). Then again it’s another discussion about performance/memory since after Java 6, “new” is not causing almost any performance problems. For memory, I’d say this code snippet doesn’t cause any memory-leaks, and for the rest memory is so cheap. I don’t think it’d be an issue :)

    May 28, 2009, 1:25 PM
  3. Paul Holser

    Yep –> http://pholser.com/writings/concisions.html

    May 29, 2009, 6:36 AM
  4. Balaji

    Very nice! I’ve been wondering about double brace lately. Do you have any thoughts about using Array lists instead?

    May 29, 2009, 6:41 AM
  5. Isa Goksu

    @Balaji, I would use Varargs if I’m not using double brace.

     

    May 29, 2009, 3:37 PM

Leave a Reply

Name (required)
Mail (required)
Website