java.util.Map is broken in Java 5

Java 5 added generics. The collection classes was modified to make use generics to provide compile-time type-safe collections. Sadly, this was not done properly.

The worst problem is in the interface java.util.Map:

public interface Map<K,V> {
    // more methods...

    V get(Object key);
    V remove(Object key);
    boolean containsKey(Object key);
    boolean containsValue(Object key);
}

The key parameters to these methods ought to be declared to be K and not Object. Now we don’t get any type-safety for those methods. If you create a HashMap<String,String> and then by mistake try to use an int as key when looking up a value, you will not get any compile-time error. Worse yet, you will not even get any run-time error, it will just appear as if there is no value with that key (which in some sense is correct).

This can cause hard to find bugs like this:

public class MapTest {
    private Map<String,String> map = new HashMap<String,String>();

    public void setFoo(int i, String s) {
        map.put(String.valueOf(i), s);
    }

    public String getFoo(int i) {
        return map.get(i); // OOPS, should have been String.valueOf(i)
    }
}

(Yes, this code is pretty stupid, but it’s only a simple example.)

There are similar problems in java.util.Collection (contains and remove methods) and some other interfaces, but that’s less serious since they are not used very often. However, it’s very serious in java.util.Map since you always use the get method.

This entry was posted in Java. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *



(this is a captcha)