[英]Cannot convert from not generic subclass to generic superclass
I'm trying to get interface instance depending on what type T is. 我试图根据类型T获得接口实例。 Place or something else that extends BaseDictionary.
放置或扩展BaseDictionary的其他内容。
public static <T extends BaseDictionary> IDictionaryDataSource<T> getEntityDataSourceInstance(Class<T> clazz,
Context cxt) {
if (Place.class.isAssignableFrom(clazz)) return (IDictionaryDataSource<T>) new PlaceDataSource(cxt);
//here some other types, same lines
return null;
}
public abstract class BaseDictionary{}
public class Place extends BaseDictionary{}
public interface IDictionaryDataSource<T extends BaseDictionary>{}
public abstract class BaseDictionaryDataSource<T extends BaseDictionary> implements IDictionaryDataSource<T>{}
public class PlaceDataSource extends BaseDictionaryDataSource<Place>{}
And I get 我得到
Type mismatch: cannot convert from PlaceDataSource to IDictionaryDataSource<T>
or 要么
Type safety: Unchecked cast from PlaceDataSource to IDictionaryDataSource<T>
if I cast it like above. 如果我像上面那样投
Can you explain why do compile error and warning occur? 您能解释为什么发生编译错误和警告吗?
It will be called here 它会在这里被称为
public static <T extends BaseDictionary> DictionaryElementPickerFragment<T> newInstance(Class<T> clazz, Context cxt){
//somecode here
fragment.setDataSource(DictUtils.getEntityDataSourceInstance(clazz, cxt));
}
I've tried to find answer here and in google but no success.I would appreciate any help. 我试图在这里和Google中找到答案,但没有成功。我将不胜感激。 Now I think like this
现在我想这样
There is no helper method to work around the problem, because the code is fundamentally wrong.
没有解决此问题的辅助方法,因为代码根本上是错误的。
Thanks in advance. 提前致谢。
This more concrete example illustrates your problem which is one of type parameter variance . 这个更具体的例子说明了您的问题,它是类型参数差异之一 。
void foo(List<String> stringList, Integer anInteger) {
List<Object> objList = (List<Object>) stringList;
objList.add(anInteger); // Violation -- adding an object to a list of strings
// could cause someone getting a "String" to get an
// Integer stead
}
so a List<String>
is not a List<Object>
although it is a List<? extends Object>
所以
List<String>
不是List<Object>
尽管它是List<? extends Object>
List<? extends Object>
. List<? extends Object>
。
In your specific instance you can't cast 在您的特定情况下,您无法投放
PlaceDataSource
toIDictionaryDataSource<T>
PlaceDataSource
为IDictionaryDataSource<T>
PlaceDataSource
is an IDictionaryDataSource<Place>
, but the only thing we know about <T>
is that it extends BaseDictionary
which is a super-class of BaseDictionary
. PlaceDataSource
是 IDictionaryDataSource<Place>
,但我们知道的唯一的事情<T>
是它扩展BaseDictionary
这是一个超一流的BaseDictionary
。
So you can cast a PlaceDataSource
to 因此,您可以将
PlaceDataSource
到
IDictionaryDataSource<Place>
or to IDictionaryDataSource<Place>
或 IDictionaryDataSource<? super Place>
IDictionaryDataSource<? super Place>
IDictionaryDataSource<? super Place>
or to IDictionaryDataSource<? super Place>
或 IDictionaryDataSource<? extends BaseDictionary>
IDictionaryDataSource<? extends BaseDictionary>
IDictionaryDataSource<? extends BaseDictionary>
but not to an IDictionaryDataSource<T>
because T
is not guaranteed to be Place
, and doing so would lead to a mismatch between the actual type parameter Place
and the formal type parameter T
. 而不是
IDictionaryDataSource<T>
因为不能保证T
是Place
,否则将导致实际类型参数Place
和形式类型参数T
不匹配。
That is not secure implementation and it is dangerous to cast because ( Place.class.isAssignableFrom(clazz)
saves you here): 那不是安全的实现,并且因为(
Place.class.isAssignableFrom(clazz)
在这里节省了您的Place.class.isAssignableFrom(clazz)
,所以进行转换很危险:
T
is a generic type and you're replacing it with definite Place
. T
是泛型类型,您将其替换为确定Place
。
What if I have 如果我有怎么办
public class Home extends BaseDictionary{}
public class HomeDataSource extends BaseDictionaryDataSource<Home>{}
And then I invoke getEntityDataSourceInstance
with Home
class but get PlaceDataSource
which cannot be cast to HomeDataSource
(IDictionaryDataSource) which I expect. 然后,我用
Home
类调用getEntityDataSourceInstance
,但是得到PlaceDataSource
,它不能转换为我期望的HomeDataSource
(IDictionaryDataSource)。 So I'll end up having ClassCastException
. 因此,我最终将遇到
ClassCastException
。
It looks like getEntityDataSourceInstance
should be an instance method in the BaseDictionary
class, not a static method. 看起来
getEntityDataSourceInstance
应该是BaseDictionary
类中的实例方法,而不是静态方法。
A subclass will know which type of DictionaryDataSource
to create. 子类将知道要创建哪种
DictionaryDataSource
类型。
尝试@SuppressWarnings(“ unchecked”)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.