java泛型 - 强制转换为List <SomeType>在未转换为SomeType时发出未经检查的强制转换警告

Mr_*_*s_D 5 java generics casting type-safety code-design

为什么这个 :

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

在此期间不会生成任何警告:

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

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

我怎样才能安抚警告?
作为一种设计是这种方法声明一个气味?

public <T> List<byte[]> getData(T data)
Run Code Online (Sandbox Code Playgroud)

是一个在不同类中使用不同数据类型实现的接口方法 - 所有实现的第一行都是这样的转换

Kat*_*ona 9

您收到警告,因为演员表(List<ScanResult>) data不安全.由于类型擦除,List<ScanResult>List在运行时期间,因此将不会对列表的元素类型进行真正的类型检查.也就是说,即使List<String>您将参数作为参数,该演员也会成功,稍后ClassCastException当您尝试访问该列表时,您将获得:

ScanResult result = data.get(0); // ClassCastException: String
Run Code Online (Sandbox Code Playgroud)

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

public interface DataProvider<T> {
    public List<byte[]> getData(T data);
}
Run Code Online (Sandbox Code Playgroud)

然后在实现时定义特定的类型参数:

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) {
    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道它是否适合您的需求.

  • @Mr_and_Mrs_D`(位置)数据是类型安全的,因为`Location`不是泛型类型,只有在转换为泛型类型时才会发出`unchecked cast`警告,因为类型参数由于类型擦除而丢失(并且只有`List`在你的情况下"仍然". (2认同)