2011-02-02 46 views
2

我有一个CacheListener<T>和实现CacheListener<Activity>一个CacheListenerLoaderJava的泛型通用工厂没有编制

我然后有一个Provider<CacheListenerLoader>吉斯所以类型必须是CacheListenerLoader所以谷歌产生正确的。

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和类的类型,这样我的正确组合m在编译时保证类类型查找的结果是可以处理给定类的东西。

我Activity.class和温度传递给我的put方法和工作正常,并检查类型。关键是上面的第四行不起作用,这看起来像泛型在这里失败了,但我不知道为什么,因为它是编译时的事情。

+3

“OurCacheListener”类型适合在哪里?你只要提到`CacheListener`并且`CacheListenerLoader`实现`CacheListener`。 – ColinD 2011-02-02 16:16:36

回答

6

我打算假设CacheListener是正确的类型,你想要做的就是将Provider<CacheListenerLoader>传递给put方法。

这里的问题是Provider<CacheListenerLoader>不是泛型世界中Provider<CacheListener<Activity>>的子类型。这就像你不能将List<Integer>分配给List<Number>类型...因为如果你这样做了,你可以将Double加入List<Number>,然后尝试从List<Integer>中检索它们作为Integer s,从而导致一个ClassCastException

当然,因为你不能给你的供应商添加任何东西,这不是一个问题。但你仍然必须告诉类型系统!你需要做的是改变put到签名:

private <T> void put(Class<T> clazz, 
        Provider<? extends CacheListener<T>> provider) 

这是说你只是想任何供应商,可以返回的东西是一个CacheListener<T>而且你不需要能够调用任何方法试图消费CacheListener<T>

0

你碰上了一个泛型的限制离子:提供者和提供者不兼容,即使A扩展或实现B.