views:

72

answers:

4

I recently ran across a set of code which instantiated local maps as following:

HashMap<String, Object> theMap = new HashMap<String, Object>();

Typically, when I've seen HashMaps used (and used them myself), the local variables are simply Map (the interface), rather than being tied to the specific implementation. Obviously this is required if the Map could potentially be instantiated as various Map types (e.g. accepting a parameter). However, in the case of something like the above where it's defined and instantiated at the same point, is there an underlying reason to only use the interface type, or is it simply style/convention?

+6  A: 

Declaring the object as a Map will allow the compiler to protect you from calling methods which are specific to HashMap. This will allow you to substitute another Map implementation in the future without worrying about having method calls which do not exist in the Map interface.

James Van Huis
Definitely on-board with this point. The beauty of passing `theMap` around as a `Map` instead of a `HashMap` is that if you later decide you want a Binary Search Tree (TreeMap) or a synchronized Hashtable instead, all you have to do is change your declaration to `Map<String,Object> theMap = new TreeMap<String,Object>();` instead. The rest of your code won't need to change.
Brent Nash
+6  A: 

(I originally misunderstood the question based on the title, but I've included both type and variable conventions as both are interesting.)

What's important is that it's a map: something you look things up in. The rest is an implementation detail.

I would suggest giving it a semantic name, e.g.

Map<String, Object> nameToSessionMap = ...

... that way when you read the code, you'll know what the keys and values are meant to be.

As for the type of the variable - again, I'd typically use the interface rather than the implementation partly because it indicates I'm not using any members which are specific to the type. I don't want to emphasize the implementation in the code, usually... it means when I do care about the implementation, I can make that more obvious.

Jon Skeet
I'm all on board the semantic naming. My example is just a genericly named toy for the purposes of the question, but good point.
Dusty
I had a friend in a high school CS class that did the exact opposite of what you suggest. He used variable/function names that were completely unrelated to the semantics, so his code looked something like `int dolphin = elephant(walrus, monkey);`. You can imagine how much the instructor loved grading his work. ;-)
Aaron Novstrup
+1  A: 

In general people use mostly Map to make the least amount of assumptions on the implementation.

It cannot be that the Classname is used for the additional methods as only clone() is added by HashMap, which has fallen in disuse (for good reasons).

What could be is that the map needs to be Serializable for one reason or another, and the plain Map interface does not extend it, but HashMap does implement it.

Peter Tillemans
+2  A: 

Even in this case, it keeps it generic. Coding to interface ensures you are using a Map and not a specific implementation of it.

fastcodejava