簡體   English   中英

java泛型 - 強制轉換為List <SomeType> 在轉換為SomeType時沒有檢查未選中的投射警告

[英]java generics - cast to List<SomeType> issues unchecked cast warning while cast to SomeType not

為什么這個 :

public <T> List<byte[]> getData(T data) {
    Location loc = (Location) data;
    // ...
}

在此期間不會生成任何警告:

public <T> List<byte[]> getData(T data) {
    List<ScanResult> scanRes = (List<ScanResult>) data;
    // ...
}

生成Type safety: Unchecked cast from T to List<ScanResult>

我怎樣才能安撫警告?
作為一種設計是這種方法聲明一個氣味?

public <T> List<byte[]> getData(T data)

是一個在不同類中使用不同數據類型實現的接口方法 - 所有實現的第一行都是這樣的轉換

您收到警告,因為(List<ScanResult>) data不安全。 由於類型擦除List<ScanResult>在運行時將是List ,因此不會對列表的元素類型進行真正的類型檢查。 也就是說,即使您將List<String>作為參數,該轉換也會成功,稍后當您嘗試訪問該列表時,您將獲得ClassCastException

ScanResult result = data.get(0); // ClassCastException: String

避免它的一種方法是使接口通用:

public interface DataProvider<T> {
    public List<byte[]> getData(T data);
}

然后在實現時定義特定的類型參數:

public class DataProviderFromLocation implements DataProvider<Location> {
    public List<byte[]> getData(Location data) {
    }
}

public class DataProviderFromScanResultList implements DataProvider<List<ScanResult>> {
    public List<byte[]> getData(List<ScanResult> data) {
    }
}

我不知道它是否適合您的需求。

來自Angelika Langer的Java Generics FAQs

當源代碼中存在強制轉換表達式時,我們准備應對ClassCastException,但是當我們從字符串列表中提取元素時,我們不期望ClassCastException。 這種意外的ClassCastException被認為違反了類型安全原則。 為了引起對可能不安全的強制轉換的注意,編譯器在翻譯可疑的強制轉換表達式時會發出“未經檢查”的警告。

所以我的第一個問題的答案是對SomeType將失敗,然后如果類不兼容 - 而List<ScanResult> scanRes = (List<ScanResult>) data; 在運行時只是List scanRes = (List) data; 如果data任何 List實現,則不會失敗 - 但可能導致CCE位於代碼庫的遠程且完全不相關的部分 - 因此調試將非常困難 - 因此警告。

另一種方式(由@erickson 在這里 ):

通過自己的預測,您“遵守Java泛型的保修條款”:如果引發ClassCastException ,它將與源代碼中的強制轉換關聯,而不是編譯器插入的不可見轉換。

暫無
暫無

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

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