It seems to me that Guice implementation is doing some very tricky things when dealing with generics. It looks like it knows at runtime about generic types used at compile time. Let’s see a simple example:
@Inject
public void Bar(Provider<Foo> genericInjector){
...
At runtime Guice will inject a correct implementation of Provider here (i.e. the one that provides Foo instances). But from what I know, generic types are erased at runtime (see: Type Erasure ). So all that Guice really sees at runtime is:
@Inject
public void Bar(Provider genericInjector){
....
So how is it possible that Guice knows which implementation of Provider to inject?
No, type erasure doesn’t erase everything. You can still get the types of fields, parameters etc. The
Provider<Foo>information is still present at execution time. SeeMethod.getGenericParameterTypesfor example.What isn’t preserved is the type information about specific objects. For example, if I write:
There’s no way that can work out that it’s an
ArrayList<String>because the object doesn’t have that information any more.See the Java Generics FAQ for a lot more information.