Funky Object Initialization
Tuesday, October 25, 2011 |I’ve been using a technique a lot, recently, for initializing an object a bit more succinctly. It looks pretty odd, I’ll admit, enough so that it really caught a coworker of mine off guard. If you’ve been reading my recent REST posts, you’ve seen this a few times. I like it a lot, so I thought I’d a take a quick look at it.
Here’s the technique in question:
1
2
3
4
Map<String, Object> map = new HashMap<String, Object>() {{
put("foo", "abc");
put("bar", "123");
}};
I’m not a language geek by any reasonable stretch of the imagination, so I can’t see in definitive (or maybe even accurate) terms what’s going on here, but it seems to me to be very much like the instantiation of an anonymous inner class. We’ve all seen those:
1
2
3
4
5
6
Thread t = new Thread(name) {
@Override
public void run() {
// foo
}
}
Nothing unusual there. What makes this so interesting is (if my educated guess is correct) is the static initializer block we’ve declared ({ put…; put…;}
). Technically, I think we’re subclassing HashMap and specifying a static initializer. Technicalities aside, what this does is allow us to execute initialization code in the context of the newly created object before it’s returned to the enclosing code. What I like about this is that it makes the code much more concise, and can be collapsed in IDEs and editors that support such things. It also allows me to create a Map
(or List
or Set
or Foo
or…) and initialize it inside a method call:
1
2
3
4
someObject.someMethodThatTakesAList(new List<String>() {{
add("foo");
add("bar");
}});
That’s some fancy kung fu. :)
I didn’t invent or discover this technique, but I’ve found it to be extremely useful. Now that you have it in your toolbox, maybe you will too.