java泛型-转换到列表<;SomeType>;在强制转换为某些类型时发出未选中强制转换警告

java泛型-转换到列表<;SomeType>;在强制转换为某些类型时发出未选中强制转换警告,java,generics,casting,type-safety,code-design,Java,Generics,Casting,Type Safety,Code Design,为什么会这样: public <T> List<byte[]> getData(T data) { Location loc = (Location) data; // ... } 公共列表getData(T数据){ 位置loc=(位置)数据; // ... } 在以下情况下,不会生成任何警告: public <T> List<byte[]> getData(T data) { List<ScanResult>

为什么会这样:

public <T> List<byte[]> getData(T data) {
    Location loc = (Location) data;
    // ...
}
公共列表getData(T数据){
位置loc=(位置)数据;
// ...
}
在以下情况下,不会生成任何警告:

public <T> List<byte[]> getData(T data) {
    List<ScanResult> scanRes = (List<ScanResult>) data;
    // ...
}
公共列表getData(T数据){
列表扫描=(列表)数据;
// ...
}
生成
类型安全:未选中从T到列表的强制转换

我怎样才能平息警告?
作为一种设计,这种方法是一种气味吗

public <T> List<byte[]> getData(T data)
公共列表getData(T数据)

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

您会收到警告,因为强制转换
(列表)数据
不安全。由于运行时,
List
将是
List
,因此不会对列表的元素类型进行真正的类型检查。也就是说,即使您获得
List
作为参数,该强制转换也将成功,稍后当您尝试访问该列表时,您将获得
ClassCastException

ScanResult result = data.get(0); // ClassCastException: String
避免这种情况的一种方法是使接口通用:

public interface DataProvider<T> {
    public List<byte[]> getData(T data);
}
公共接口数据提供程序{
公共列表getData(T数据);
}
然后在实现中定义特定的类型参数:

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) {
    }
}
公共类DataProviderFromLocation实现DataProvider{
公共列表getData(位置数据){
}
}
公共类DataProviderFromScanResultList实现DataProvider{
公共列表getData(列表数据){
}
}
我不知道它是否适合你的需要。

安吉丽卡·兰格的

我们准备在有演员阵容时处理ClassCastException s 表达式,但我们不期望ClassCastException 当我们从字符串列表中提取一个元素时。这种 意外的ClassCastException被视为违反 类型安全原则。为了引起人们对潜在风险的关注 不安全强制转换编译器在运行时发出“未检查”警告 翻译可疑的演员表情

因此,我的第一个问题的答案是,对
SomeType
的转换将失败,然后如果类不兼容-而
List scanRes=(List)数据在运行时只是
列表扫描=(列表)数据数据
是任何列表实现,则代码>不会失败-但可能会导致代码库的远程和完全不相关部分出现CCE-因此调试非常困难-因此发出警告

另一种说法(作者@erickson):

通过预先执行自己的强制转换,您“遵守了Java泛型的保修条款”:如果引发
ClassCastException
,它将与源代码中的强制转换相关联,而不是编译器插入的不可见强制转换


为什么是
Location loc=(Location)数据类型安全?如果我调用
getData(“some string”)
它会在
Location loc=(Location)“some string”中失败吗再次使用CCE+1用于参数化接口idea@Mr_and_Mrs_D
(位置)数据
是类型安全的,因为
位置
不是泛型类型,
未选中强制转换
警告仅在强制转换为泛型类型时发出,因为类型参数由于类型擦除而丢失(并且在您的情况下只有
列表
“保留”)@Mr_and_Mrs_会这样想:在运行时,
T
已被擦除为
Object
。但是将
对象
强制转换到
位置
仍然是一个选中的强制转换,如果错误,将很快失败。相反,对
T
的强制转换将被取消选中。@PaulBellora:谢谢你澄清了这一点-我显然没有探究“取消选中”是什么意思-请看我的回答说明,使用泛型方法不会买任何东西-它可能是
公共列表getData(对象数据)