Q:

How do I make Java to infer the right generic map type for my typesafe map literals?

I am trying to write a typesafe map literal helper class in java that can generate maps of any type and have the compiler check that all given keys and values conform to the type of the map. For a map with two values there would be a function with the following signature:
public static <KEY, VALUE> Map<KEY, VALUE> make(final KEY key1,
        final VALUE value1,
        final KEY key2,
        final VALUE value2)

Now I would have expected that something like this would be possible:
    Map<Integer, Object> map = make(1, "bla", 3, 17);

However I get an compiler error:
Type mismatch: cannot convert from Map<Integer,Object&Serializable&Comparable<?>> to 
 Map<Integer,Object>

Is there a way to fix this? Of course, defining a function with signature make(Object... keysAndValues) would work, but I would loose the compile time typesafety. :-(

A:

The error is probably here:
Map<Integer, Object> map = make(1, "bla", 3, 17);
                                   ^^^^^     ^^

VALUE > Object can't be inferred from both String and Integer
Try any of these:
// Helping the compiler to infer Object for VALUE
Map<Integer, Object> map = make(1, (Object)"bla", 3, 17);

// Explicitly bind VALUE to Object
Map<Integer, Object> map = MyClass.<Integer, Object>make(1, "bla", 3, 17);

// If you don't need to write into "map" (as user pmnt also suggested)
Map<Integer, ?> map = make(1, "bla", 3, 17);

A:

Your code will work if you modify the Map's signature in the calling method:
No changes required to make
public static <A, B> Map<A, B> make(final A key1, final B value1,
        final A key2, final B value2) {
    Map<A, B> map = new HashMap<A, B>();
    map.put(key1, value1);
    map.put(key2, value2);
    return map;
}

Make's caller
You must change Map<String, Object> to Map<String, ? extends Object>:
public static void main(String[] args) {

    @SuppressWarnings("unused")
    Map<String, ? extends Object> m = make("a", new Integer(1), "2", "efg");

}

EDIT1: OpenJDK 1.6 + Eclipse Indigo compiler
EDIT2: When building generic maps like that, you must accept that you have to downcast when it comes to retrieving the values.
EDIT3: Is there a way to fix this? Of course, defining a function with signature make(Object... keysAndValues) would work, but I would loose the compile time typesafety.
You will always loose compile time safety at a certain point. At least when it comes to retrieval.

