簡體   English   中英

轉換為泛型類型(T)會發出“未經檢查的強制轉換”警告

[英]Cast to generic type (T) gives “unchecked cast” warning

關於帶有列表的泛型有界類型,我遇到了一個小問題。 請幫忙!

Model.java

public class Model {
}

ClassA.java

public class ClassA<T extends Model> {
    private List<T> models;

    public ClassA() {
        models.add((T) new Model());
    }
}

它在這一行給我一個從模型到T警告的未經檢查的強制轉換:

models.add((T) new Model());

我知道我收到了這個警告,因為我可以安全地從一個子類投射到一個超級類而不是反過來。

有沒有辦法解決這個問題,還是我可以安全地抑制警告?

你不能做你想做的事。

由於TModel的子類:

  • 每個T都是一個模型
  • 但不是每個模型都是T。

如果通過調用new Model()來構造新模型,則實例恰好是Model而不是任何子類的實例。

Subclass擴展Superclass的地方 ,你永遠不能成功地做到這一點:

(Subclass) new Superclass();

因此,您無法成功將新模型強制轉換為T的實例。

編譯器只會給你一個警告,你可以忽略或抑制,但是當你運行你的程序並調用add()方法時你會得到一個ClassCastException

舉個例子

public static void main(String[] args) {
    ClassA<SubModel> models = new ClassA<>();
    for (SubModel model : models.getModels()){
        model.run(); // runtime ClassCastException
    }
}
public static class ClassA<T extends Model> {
    private List<T> models = new LinkedList<>();

    public ClassA() {
        models.add((T)new Model()); // compiles and warns
    }

    public List<T> getModels() {
        return models;
    }
}
public static class SubModel extends Model {
    public void run() {
        System.out.println(this);
    }
}
public static class Model {
}

您添加到models的對象是運行時類型Model ,它沒有run()方法。

當您最終嘗試將對象用作SubModel類型的對象時,您將像在main()方法中那樣獲得ClassCastException

你真的不應該這樣做,即。 將父類型對象添加到可能的suptype類型對象。

在構造函數中添加元素之前,需要初始化列表。 我想你可能只復制了相關的代碼片段,這就是為什么它被遺漏了。

此外,我認為唯一的方法是抑制警告。 更多信息只有協方差,逆變在這里: 協方差,不變性和逆變性用簡單的英語解釋?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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