我有一个CacheListener<T>
和一个CacheListenerLoader
来实现CacheListener<Activity>
。
然后我有一个Provider<CacheListenerLoader>
Guice,所以类型必须是CacheListenerLoader,所以google会生成正确的。
第4行无法编译:
CacheListenerLoader listTemp;
OurCacheListener<Activity> t2 = listTemp;
Provider<CacheListenerLoader> prov;
Provider<OurCacheListener<Activity>> temp = prov;
这很重要,因为我试图调用这个方法:
private <T> void put(Class<T> klass, Provider<OurCacheListener<T>> provider)
然后传递Provider和类类型的正确组合,以便在编译时保证类类型查找能够处理给定类的内容。
我将Activity.class和temp传递给我的put方法,并且工作正常并检查类型。关键是上面的第4行不起作用,看起来仿制药让我失败了,但我不确定为什么因为它是编译时的事情。
答案 0 :(得分:6)
我将假设CacheListener
是正确的类型,您要做的是将Provider<CacheListenerLoader>
传递给put
方法。
这里的问题是Provider<CacheListenerLoader>
不是泛型世界中Provider<CacheListener<Activity>>
的子类型。这就像你不能将List<Integer>
分配给List<Number>
类型...因为如果你这样做,你就可以将Double
添加到List<Number>
然后尝试从List<Integer>
作为Integer
检索它们,从而导致ClassCastException
。
当然,由于您无法向提供商添加任何内容,因此这不是问题。但你还是要告诉类型系统!您需要做的是将put
的签名更改为:
private <T> void put(Class<T> clazz,
Provider<? extends CacheListener<T>> provider)
这表示您只想要任何可以返回CacheListener<T>
内容的提供程序,并且您不需要能够调用任何尝试使用CacheListener<T>
的方法。
答案 1 :(得分:1)
你需要使用一些通配符。哪些对我来说并不容易,因为你提供的代码很少,但我会说像
Provider<? extends OurCacheListener<Activity>> temp = prov;
供参考,请阅读
答案 2 :(得分:0)
你偶然发现了一个泛型限制:即使A扩展或实现B,提供者和提供者也不兼容。