Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法从非泛型子类转换为泛型超类_Java - Fatal编程技术网

Java 无法从非泛型子类转换为泛型超类

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

我试图根据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>{}
公共静态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
是一个泛型类型,您将用definite
Place
替换它

如果我有呢

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
}