[英]Cannot convert from not generic subclass to generic superclass
我試圖根據類型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));
}
我試圖在這里和Google中找到答案,但沒有成功。我將不勝感激。 現在我想這樣
沒有解決此問題的輔助方法,因為代碼根本上是錯誤的。
提前致謝。
這個更具體的例子說明了您的問題,它是類型參數差異之一 。
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>
List<? extends Object>
。
在您的特定情況下,您無法投放
PlaceDataSource
為IDictionaryDataSource<T>
PlaceDataSource
是 IDictionaryDataSource<Place>
,但我們知道的唯一的事情<T>
是它擴展BaseDictionary
這是一個超一流的BaseDictionary
。
因此,您可以將PlaceDataSource
到
IDictionaryDataSource<Place>
或 IDictionaryDataSource<? super Place>
IDictionaryDataSource<? super Place>
或 IDictionaryDataSource<? extends BaseDictionary>
IDictionaryDataSource<? extends BaseDictionary>
而不是IDictionaryDataSource<T>
因為不能保證T
是Place
,否則將導致實際類型參數Place
和形式類型參數T
不匹配。
那不是安全的實現,並且因為( Place.class.isAssignableFrom(clazz)
在這里節省了您的Place.class.isAssignableFrom(clazz)
,所以進行轉換很危險:
T
是泛型類型,您將其替換為確定Place
。
如果我有怎么辦
public class Home extends BaseDictionary{}
public class HomeDataSource extends BaseDictionaryDataSource<Home>{}
然后,我用Home
類調用getEntityDataSourceInstance
,但是得到PlaceDataSource
,它不能轉換為我期望的HomeDataSource
(IDictionaryDataSource)。 因此,我最終將遇到ClassCastException
。
看起來getEntityDataSourceInstance
應該是BaseDictionary
類中的實例方法,而不是靜態方法。
子類將知道要創建哪種DictionaryDataSource
類型。
嘗試@SuppressWarnings(“ unchecked”)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.