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