Binding a Map with type

1,930 views
Skip to first unread message

Andrew Swift

unread,
Nov 14, 2007, 5:44:57 AM11/14/07
to google-guice
I am trying to inject some test data into one of my MockServices

In the service I have

@Inject @Named("testData") Map<Integer, BigDecimal> customerBalances;


In the Module I have

Map<Integer,BigDecimal> map;
binder.bind(map.getClass())
.annotatedWith(new NamedAnnotation("testData"))
.toInstance(customerTotals);

The compiler says

The method toInstance(capture-of ? extends Map) in the type
LinkedBindingBuilder<capture-of ? extends Map> is not applicable for
the
arguments (Map<Integer,BigDecimal>)

Are there any workarounds to solve this ? Or do i need to use non type
safe Maps.

cheers

Andy

Dhanji R. Prasanna

unread,
Nov 14, 2007, 6:07:44 AM11/14/07
to google...@googlegroups.com
You need to bind with a TypeLiteral, because java does not support
literals for generic types (yet).

bind(new TypeLiteral<Map<Integer, BigDecimal>> { })
.annotatedWith(...)
.toInstance(myMap);

Kludgey as it is, this innovation never ceases to amaze me in its ingenuity. =)

Dhanji.

Stuart McCulloch

unread,
Nov 14, 2007, 6:12:39 AM11/14/07
to google...@googlegroups.com
On 14/11/2007, Andrew Swift <andrewp...@gmail.com> wrote:

I am trying to inject some test data into one of my MockServices

In the service I have

@Inject @Named("testData") Map<Integer, BigDecimal> customerBalances;


In the Module I have

Map<Integer,BigDecimal> map;
binder.bind(map.getClass())
                .annotatedWith(new NamedAnnotation("testData"))
                .toInstance(customerTotals);

try something like:

   binder.bind(new TypeLiteral<Map<Integer,BigDecimal>>(){})

      .annotatedWith(new NamedAnnotation("testData"))
         .toInstance(customerTotals);

this uses an anonymous class to provide the generic type to Guice - this is needed to get
around the "type-erasure" issue ( as map.getClass() in your example just returns Map )


The compiler says

The method toInstance(capture-of ? extends Map) in the type
LinkedBindingBuilder<capture-of ? extends Map> is not applicable for
the
arguments (Map<Integer,BigDecimal>)

Are there any workarounds to solve this ? Or do i need to use non type
safe Maps.

cheers

Andy







--
Cheers, Stuart

Dhanji R. Prasanna

unread,
Nov 14, 2007, 6:16:59 AM11/14/07
to google...@googlegroups.com
More importantly in your case parameterized type information is not
available at runtime because java uses erasure typing for generics. So
map.getClass() == map.getClass() for *any* two Map<K, V> declared
variables.

Put another way, generic types are no different from raw types to the
JVM due to the fact that they are erased to raw types by the compiler
(and only retained in the type reflection).

Dhanji.

Andrew Swift

unread,
Nov 14, 2007, 7:07:26 AM11/14/07
to google-guice
That is exactly what I was after.

Thanks :)

On Nov 14, 12:12 pm, "Stuart McCulloch" <mccu...@gmail.com> wrote:

Reply all
Reply to author
Forward
0 new messages