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(对象数据)
。