通用工厂的Java通用不编译

Dea*_*ler 2 java generics guice

我有一个CacheListener<T>和一个CacheListenerLoader实现CacheListener<Activity>.

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

第4行无法编译:

CacheListenerLoader listTemp;
OurCacheListener<Activity> t2 = listTemp;
Provider<CacheListenerLoader> prov;
Provider<OurCacheListener<Activity>> temp = prov;
Run Code Online (Sandbox Code Playgroud)

这很重要,因为我试图调用这个方法:

private <T> void put(Class<T> klass, Provider<OurCacheListener<T>> provider)
Run Code Online (Sandbox Code Playgroud)

然后传递Provider和类类型的正确组合,以便在编译时保证类类型查找能够处理给定类的内容.

我将Activity.class和temp传递给我的put方法,并且工作正常并检查类型.关键是上面的第4行不起作用,看起来仿制药在这里让我失望,但我不确定为什么因为它是编译时间的事情.

Col*_*inD 6

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

这里的问题是a Provider<CacheListenerLoader>不是Provider<CacheListener<Activity>>泛型世界的子类型.这就像你不能指定List<Integer>类型的那样List<Number>...因为如果你这样做,你就可以添加Doubles List<Number>然后尝试从List<Integer>as中检索它们Integer,从而导致a ClassCastException.

当然,由于您无法向提供商添加任何内容,因此这不是问题.但你还是要告诉类型系统!您需要做的是将签名更改put为:

private <T> void put(Class<T> clazz,
                     Provider<? extends CacheListener<T>> provider)
Run Code Online (Sandbox Code Playgroud)

这表示你只想要任何可以返回某个东西的提供者,CacheListener<T>并且你不需要能够调用任何试图使用的方法CacheListener<T>.