Thursday, March 12, 2009

Block Expressions

I discovered a weird Java collection initialization idiom whilst reading this post a couple days ago.


List<String> l = new ArrayList<String>() {{
add("A");
add("B");
add("C");
}};


It took me a minute to figure out what was going on. For those who haven't seen this before, the first and last curly brace define an anonymous inner class. The inner curly braces and the code therein comprise an instance initialization block for the anonymous inner class. So this code effectively create a subclass of ArrayList that adds three elements ("A", "B", and "C") to itself upon creation. It's kind of interesting, but I'm not sure how useful it is. The only place I could see using something like this would be in a class that needs a wrapped static final collection. Using this pattern would eliminate the need to build and populate a temporary collection in a static initializer and then wrap it and assign it to the static final member.

As it turns out, one of the proposals on the table for Java 7 is something called Block Expressions, which would allow you to define temporary local variables within expressions. One of the use case given for this feature is identical to the use case I outlined above.


public static final Map<Integer,Integer> primes = (
Map<Integer,Integer> t = new HashMap<Integer,Integer>();
t.put(1, 2);
t.put(2, 3);
t.put(3, 5);
t.put(4, 7);
Collections.UnmodifiableMap(t));


Block expressions have other uses beyond this so it may be a good idea to add them to the language, but I'm actually partial to the anonymous inner class with instance initializer approach in this situation.


public static final Map<Integer,Integer> primes = Collections.unmodifiableMap(
new HashMap<Integer,Integer>() {{
put(1,2);
put(2,3);
put(3,5);
put(4,7);
}});

No comments: