Mar 2, 2009
Fun Friday Trick: Generics type inference + static imports = don’t wait for Java 7
Welcome to another fun edition of fun friday on a fun monday.
Today, we’ll see a very simple trick, that uses the regular generics type inference with a factory method and static imports, to make generics more readable.
Reading the java 7 language “pre” proposals (from polls and all), and especially the one about adding more type inference on generic objects construction, i remembered a very simple trick i stumbled upon years ago.
What if you named your factory method as a constructor and imported it using the static import feature ? Turns out, i kinda like how it cleans up the code.
Today, we’re using this, and it’s a mouthful:
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
I think the java 7 proposal (when it’s released, there’s no draft for it yet, only informal polls, and a starting proposal here) will allow to turn it into
Map<String, List<String>> anagrams = new HashMap<>();
First of, notice the ugly empty <>, it would look cleaner without it, but because of backwards compatibility, it might not be “possible”. We’ll see.
While today’s trick turns it into this, (assuming it was added to HashMap of course)
// in java.util.HashMap for instance // very common code except for the name public static <K, V> HashMap<K,V> HashMap() { return new HashMap<K, V>(); } // in your code, where the magic happens import static java.util.HashMap.HashMap; // oooh, pretty Map<String, List<String>> anagrams = HashMap();
It’s less code. It’s cleaner without the <>. It looks a little like a C++ constructor – from a distance (: – , but it has added perks too, it’s a real factory method, so you can verify arguments and throw exceptions *without* creating objects, and so on.
The way we’re doing it today is relatively easy to write since IDEs are helping, so you could see the java 7 proposal as of limited value, but code is written once, and read multiple times. That’s why i think both the proposal and today’s trick have value.
The IDEs are however a little less successfull at providing you intellisense for static imports it seems. You can solve that by modifying the default class template, or by typing HashMap.HashMap() and refactoring it to a static import (or soon will be able to do so).
You don’t have to wait for java 7 for generics to become easier to use, and even though it would be cleaner if the function was in, say, HashMap, you could still have a helper class à la java.util.Collections or google collections’ Lists and Maps, and so on, if you really wanted to.
So, this is really about a way of naming factory methods and importing them statically, making it rather transparent to use today, without waiting for potential language changes. Both are not perfectly clean, but i don’t think we’ll be getting a real clean way (full type inference on the variable) any time soon, so, in the meantime, pick your poison.
Next up: more composite tricks, and the real reason why they might be useful to you. Yes, there is a plan behind the randomness.