我正在尝试根据T的类型获取接口实例。放置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>{}
我得到了
Type mismatch: cannot convert from PlaceDataSource to IDictionaryDataSource<T>
或
Type safety: Unchecked cast from PlaceDataSource to IDictionaryDataSource<T>
如果我像上面那样投射它。
你能解释为什么会出现编译错误和警告吗?
这里将被称为
public static <T extends BaseDictionary> DictionaryElementPickerFragment<T> newInstance(Class<T> clazz, Context cxt){
//somecode here
fragment.setDataSource(DictUtils.getEntityDataSourceInstance(clazz, cxt));
}
我试图在这里和谷歌找到答案,但没有成功。我将不胜感激任何帮助。 现在我想像这样
没有帮助方法来解决这个问题,因为代码根本就是错误的。
提前致谢。
答案 0 :(得分:1)
这个更具体的例子说明了你的问题,它是类型参数方差之一。
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
}
所以List<String>
不是List<Object>
,尽管它是List<? extends Object>
。
在您的特定实例中,您无法投射
PlaceDataSource
至IDictionaryDataSource<T>
PlaceDataSource
是 IDictionaryDataSource<Place>
,但我们对<T>
唯一了解的是它扩展了BaseDictionary
这是一个超类BaseDictionary
。
所以你可以将PlaceDataSource
投射到
IDictionaryDataSource<Place>
或IDictionaryDataSource<? super Place>
或IDictionaryDataSource<? extends BaseDictionary>
但不是IDictionaryDataSource<T>
,因为T
不能保证为Place
,这样做会导致实际类型参数Place
与正式参数不匹配类型参数T
。
答案 1 :(得分:0)
这不是安全的实施,因为(Place.class.isAssignableFrom(clazz)
将你保存在这里)而施展是危险的:
T
是一种通用类型,您将其替换为明确的Place
。
如果我有
怎么办?public class Home extends BaseDictionary{}
public class HomeDataSource extends BaseDictionaryDataSource<Home>{}
然后我使用getEntityDataSourceInstance
类调用Home
,但得到PlaceDataSource
,它不能转换为我期望的HomeDataSource
(IDictionaryDataSource)。所以我最终会得到ClassCastException
。
答案 2 :(得分:0)
看起来getEntityDataSourceInstance
应该是BaseDictionary
类中的实例方法,而不是静态方法。
子类将知道要创建的DictionaryDataSource
类型。
答案 3 :(得分:-3)
尝试@SuppressWarnings(“未选中”)