未经检查的强制转换:'java.lang.Class <capture <?>>'到'java.lang.Class <t>

时间:2019-04-29 21:43:08

标签: java android generics

我正在尝试在我的超类中编写以下方法:

public <T extends Downloader> T getDownloader(Context context, Integer... positions) throws Exception {

    Class<T> mClass = (Class<T>)Class.forName(getDownloaderClassName());
    T downloader = mClass.cast(mClass.getConstructors()[0].newInstance(context));
    if (downloader != null)
        downloader.setPositions(positions);

    return downloader;
}

但是,我不知道如何避免AndroidStudio告诉我

Unchecked cast: 'java.lang.Class<capture<?>>' to 'java.lang.Class<T>

关于第一行,或者我更改了

Class<T> to Class<?>

然后我必须执行直接投射

(T)mClass.getConstructors....

更精确地说,这个超类是抽象的,并且getDownloaderClassName()实际上定义如下:

public abstract String getDownloaderClassName();

以便子类可以选择需要使用getDownloader()检索的Downloader的后代。

2 个答案:

答案 0 :(得分:0)

好吧,我想我对T和?感到困惑,所以我发现了一种无警告的方式:

   public Downloader getDownloader(Context context, Integer... positions) throws Exception {

    Class<? extends Downloader> mClass = getDownloaderClassName();
    Downloader downloader = mClass.cast(mClass.getConstructors()[0].newInstance(context));
    if (downloader != null)
        downloader.setPositions(positions);

    return downloader;
}

public abstract Class<? extends Downloader> getDownloaderClassName();

然后,抽象方法变为:

@Override
public Class<? extends Downloader> getDownloaderClassName() {
    return DemoDownloader.class;
}

在后代中。

我想当我需要特定的字段或方法时,只需要强制转换getDownloader的结果即可。

答案 1 :(得分:0)

签名public <T extends Downloader> T getDownloader(Context context, Integer... positions)的类型不安全。它使getDownloader成为通用方法,这意味着无论调用者希望T是什么,在不知道T的情况下,它必须正确工作。请注意,T不会显示在任何参数类型中。这意味着具有相同确切参数的相同确切调用必须以某种方式返回类型Downloader1(如果这是一个呼叫者想要的),并且还必须返回类型Downloader2(如果这是另一个呼叫者想要的),而没有{{1} }方法,了解有关呼叫者想要的任何信息!除非getDownloader始终返回getDownloader,否则这显然是不可能的。

签名null是不同的,因为它表示public Downloader getDownloader(Context context, Integer... positions)方法返回类型getDownloader。您的Downloader方法选择要返回的事物的类型(只要它是getDownloader的子类型);调用者不会选择类型,并且不能对返回的事物做任何假设,除非它是Downloader的实例。那是安全的。