Java generic of generic factory not compiling
I have a CacheListener<T>
and a CacheListenerLoader
which imp开发者_Python百科lements CacheListener<Activity>
.
I then have a Provider<CacheListenerLoader>
Guice so the type has to be CacheListenerLoader so google produces the right ones.
Line 4 does not compile:
CacheListenerLoader listTemp;
OurCacheListener<Activity> t2 = listTemp;
Provider<CacheListenerLoader> prov;
Provider<OurCacheListener<Activity>> temp = prov;
That is important because I am trying to call this method:
private <T> void put(Class<T> klass, Provider<OurCacheListener<T>> provider)
then pass the right combination of Provider and class type so that I'm guaranteed at compile time the class type lookup results in something that can process the given class.
I pass in Activity.class and temp to my put method and that works fine and checks the types. The key is the 4th line above is not working which looks like generics is failing me here but I am not sure why since it is a compile time thing.
I'm going to assume that CacheListener
is the correct type and what you want to do is pass your Provider<CacheListenerLoader>
to your put
method.
The problem here is that a Provider<CacheListenerLoader>
is not a subtype of Provider<CacheListener<Activity>>
in the world of generics. It's just like how you can't assign a List<Integer>
to the type List<Number>
... because if you did that, you'd be allowed to add Double
s to the List<Number>
and then try to retrieve them from the List<Integer>
as Integer
s, causing a ClassCastException
.
Of course, since you can't add anything to your providers, this isn't an issue. But you still have to tell the type system that! What you need to do is change the signature of put
to:
private <T> void put(Class<T> clazz,
Provider<? extends CacheListener<T>> provider)
This says that you just want any provider that can return something that is a CacheListener<T>
and that you don't need to be able to call any methods that try to consume a CacheListener<T>
.
You need wo use some wildcards. Which ones exactly is not easy for me to tell because you provide so little code, but I'd say something like
Provider<? extends OurCacheListener<Activity>> temp = prov;
For reference, read
- Java Generics and Collections
- Angelika Langer's Generics FAQ
- Java theory and practice: Going wild with generics, Part 2
you stumbled over a generics restriction: Provider and Provider are not compatible, even if A extends or implements B.
精彩评论