users@jsr311.java.net

RE: JAX-RS: generics: <String,Object> vs <String,?>

From: Manger, James H <James.H.Manger_at_team.telstra.com>
Date: Thu, 17 Jul 2008 09:37:50 +1000

> Map<String, String> is assignable to Map<String, Object>

No, that is wrong -- as I found in Sun's Generics tutorial <http://java.sun.com/docs/books/tutorial/extra/generics/subtype.html>.

We do need to change the method signature to
  UriBuilder.build(Map<String,?> values)
to accept a Map<String,String> argument.

I found the reason Jersey was not complaining --
calling build with a Map<String,String> argument calls
the VARARG method build(Object... values)!!!

Compile & run the following code. It produces "varargs".
Change Map<String,Object> to Map<String,?> and it produces "map".
There are no compiler errors in either case.

import java.util.*;
class Generic2
{
        static String build() { return "noargs"; }
        static String build(Map<String,Object> values) { return "map"; }
        static String build(Object... values) { return "varargs"; }

        public static void main(String[] args)
        {
                Map<String,String> values = new HashMap<String,String>();
                values.put("foo", "bar");
                System.out.println(build(values));
        }
}

This makes it a bit more important to add the following method now:
  UriBuilder.build(MultivaluedMap<String,?> values)
Otherwise (if it is only added in, say, version 2) we wont get explicit errors (which we want) when version 2 code tries to call build(MultivaluedMap) in a version 1 library. Instead the call will succeed but with unexpected results.

James Manger