簡體   English   中英

無法從非通用子類轉換為通用超類

[英]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>


在您的特定情況下,您無法投放

PlaceDataSourceIDictionaryDataSource<T>

PlaceDataSource IDictionaryDataSource<Place> ,但我們知道的唯一的事情<T>是它擴展BaseDictionary這是一個超一流的BaseDictionary

因此,您可以將PlaceDataSource

  1. IDictionaryDataSource<Place>
  2. 一個IDictionaryDataSource<? super Place> IDictionaryDataSource<? super Place>
  3. 一個IDictionaryDataSource<? extends BaseDictionary> IDictionaryDataSource<? extends BaseDictionary>

而不是IDictionaryDataSource<T>因為不能保證TPlace ,否則將導致實際類型參數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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM