Java 无法从非泛型子类转换为泛型超类
我试图根据T的类型获取接口实例。放置或其他扩展BaseDictionary的内容Java 无法从非泛型子类转换为泛型超类,java,Java,我试图根据T的类型获取接口实例。放置或其他扩展BaseDictionary的内容 public static <T extends BaseDictionary> IDictionaryDataSource<T> getEntityDataSourceInstance(Class<T> clazz, Context cxt) { if (Place.class.isAssignableFrom(clazz)) return (IDict
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>{}
公共静态IDictionaryDataSource getEntityDataSourceInstance(类clazz,
上下文(cxt){
if(Place.class.isAssignableFrom(clazz))返回(IDictionaryDataSource)新的PlaceDataSource(cxt);
//这里有一些其他类型,相同的行
返回null;
}
公共抽象类BaseDictionary{}
公共类位置扩展BaseDictionary{}
公共接口IDictionaryDataSource{}
公共抽象类BaseDictionaryDataSource实现IDictionaryDataSource{}
公共类PlaceDataSource扩展BaseDictionaryDataSource{}
我得到
Type mismatch: cannot convert from PlaceDataSource to IDictionaryDataSource<T>
类型不匹配:无法从PlaceDataSource转换为IDictionaryDataSource
或
类型安全:未选中从PlaceDataSource到IDictionaryDataSource的强制转换
如果我像上面那样投
你能解释一下为什么会出现编译错误和警告吗
它将在这里命名
public static <T extends BaseDictionary> DictionaryElementPickerFragment<T> newInstance(Class<T> clazz, Context cxt){
//somecode here
fragment.setDataSource(DictUtils.getEntityDataSourceInstance(clazz, cxt));
}
公共静态字典yelementpickerfragment newInstance(类clazz,上下文cxt){
//这里有些代码
fragment.setDataSource(DictUtils.getEntityDataSourceInstance(clazz,cxt));
}
我试图在这里和谷歌上找到答案,但没有成功。我将感谢任何帮助。
现在我这样想
没有辅助方法来解决这个问题,因为代码从根本上是错误的
提前感谢。这不是安全的实现,强制转换是危险的,因为(
Place.class.isAssignableFrom(clazz)
将您保存在此处):
T
是一个泛型类型,您将用definitePlace
替换它
如果我有呢
public class Home extends BaseDictionary{}
public class HomeDataSource extends BaseDictionaryDataSource<Home>{}
公共类Home扩展BaseDictionary{}
公共类HomeDataSource扩展BaseDictionaryDataSource{}
然后我用
Home
类调用getEntityDataSourceInstance
,但得到PlaceDataSource
,它不能转换为我期望的HomeDataSource
(IDictionaryDataSource)。因此,我将使用ClassCastException
尝试@SuppressWarnings(“unchecked”)它看起来像getEntityDataSourceInstance
应该是BaseDictionary
类中的一个实例方法,而不是静态方法
子类将知道要创建哪种类型的
DictionaryDataSource
。这个更具体的示例说明了类型参数变化的问题
void foo(List stringList,Integer和Integer){
列表对象列表=(列表)字符串列表;
add(一个整数);//冲突——将对象添加到字符串列表中
//可能会导致获得“字符串”的人获得
//整数代替
}
因此,
列表
不是列表
,尽管它是一个列表。。如何根据类变量是什么实现获取特定数据源?或者我应该重写什么部分呢?反正你会得到这个警告的。但是Place.class.isAssignableFrom(clazz)
将您保存在这里,这样您就不会出现上述情况。你可以使用@suppressWarnings
annotationhmm,也许我应该使用一些神奇的模式或者一些我不知道的东西?如果你需要通用方法,请三思。也许你需要一个或两个类,然后jsut实现它们。其他解决方案是使用工厂模式
。一个很好的例子是这里没有人谈论错误。瓦西里科夫的密码没有错误。泛型在Java中的实现非常糟糕,通常它是抑制这些关于未检查强制转换的讨厌警告的唯一解决方案。错了,Frank。如果没有任何不安全类型警告,则在运行时将永远不会出现任何ClassCastException
。如果你不在乎,就用原始类型。但是,一半时间使用泛型,而忽略关于实际问题的警告(在本例中,代码确实存在bug)是毫无意义的。BaseDictionary只是一个带有getter和setter的模型,我被告知不要在那里这样做
public class Home extends BaseDictionary{}
public class HomeDataSource extends BaseDictionaryDataSource<Home>{}
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
}