tags:

views:

298

answers:

4

In Java, the Map interface is defined as,

public interface Map<K,V> {
    ...
    V get(Object key);
    ...
}

Why not?

V get(K key);

I just bumped into a nasty bug because wrong type key is used. I thought the purpose of the generics is to catch type error early during compiling. Does this defeat that purpose?

+6  A: 

Kevin Bourrillion blogged about this a while ago. Summary:

Uniformly, methods of the Java Collections Framework (and the Google Collections Library too) never restrict the types of their parameters except when it's necessary to prevent the collection from getting broken.

Personally I'm not a fan of that approach, but it does make some sense given the variance approach which has also been taken.

Jon Skeet
+4  A: 

Some good answers can be found here:

What are the reasons why Map.get(Object key) is not (fully) generic

NickDK
A: 

To add to @subtenante, Java is designed so that Java will always be backwards compatible. Generics disallow puts of the wrong type, as this does not break backwards compatibility. The easy way to make sure that the right key is being used is to do this.

K key = null;
V value = null;

Map<K,V>  mapped = new HashMap<K,V>()
.......//set the key and value..........
mapped.put(key, value)
.....
V var = mapped.get(key);

Problem solved.
One more caveat to generics, any child of a class can also be placed into a collection.

Number k= null;
Number v= null;

Map<Number,Number>  mapped = new HashMap<Number,Number>()
.......//set the key and value..........
k = double someDouble;
v = int someInt;
mapped.put(k, v)
.....

This could cause some big bugs!!

WolfmanDragon
I really don't see where erasure comes into this. Erasure should only be a problem if you are doing something "unsafe".
Tom Hawtin - tackline
Put() uses generics types. I am only complaining about get.
ZZ Coder
@ZZ Coder, I addressed the get in the top set of code, the second set of code I was pointing out another common problem some have using generics
WolfmanDragon
A: 

an object of one type can be .equals() to an object of another type. get() only requires that the object that you give it be .equals() to the key you are getting

newacct
This is not true. I get ClassCastException so the type must match.
ZZ Coder
If you get a ClassCastException then equals() is poorly implemented. It is a better idea to return false if the types are incompatible.
finnw