简体   繁体   中英

Java generic of generic factory not compiling

I have a CacheListener<T> and a CacheListenerLoader which implements 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

您偶然发现了泛型限制:即使A扩展或实现B,提供者和提供者也不兼容。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM