JLS 5.1.9定义未经检查的转换,如下所示:
让G用n个类型参数命名通用类型声明。
原始类或接口类型有未经检查的转换 G表示为
G<T1,...,Tn>
形式的任何参数化类型。从原始数组类型
G[]
到G<T1,...,Tn>[]
形式的任何数组类型类型都有未经检查的转换。使用未经检查的转换会导致编译时未经检查的警告 除非
G<...>
是其中所有类型实参都在其中的参数化类型 不受限制的通配符,或者不受限制的警告被 SuppressWarnings批注
据我了解,它说如果将原始类型转换为具有受限类型参数的泛型,则会发生未经检查的转换。那么为什么以下代码会生成未经检查的警告:
public class DoubleStar{
public static void print(Object object){
((A<String>)object).print();
}
public static void main(String[] args){
print(new Object());
}
}
class A<T>{
public void print(){
System.out.print("HELLO");
}
}
由于对象不是原始类型(AFAIK),因此上述代码为什么应生成未经检查的强制转换警告,并且在何处定义了此行为?
答案 0 :(得分:1)
您正在查看错误的部分,这就是为什么在您的示例上下文中它似乎没有意义。
您的警告是未选中的 cast 。您正在查看有关未选中的转化(related)的部分。
See 5.5.2 "Checked Casts and Unchecked Casts"
从S类型转换为T类型的转换是静态已知是正确的,当且仅当S <:T (§4.10)。
从类型S转换为参数化类型(第4.5节)T的未检查 除非至少满足以下条件之一:
- S <:T
- T的所有类型参数(第4.5.1节)都是无界通配符
- T <:S和S除了T的类型实参之外,没有X的子类型X X不包含在T的类型参数中。
除非S <:T,否则不检查从类型S到类型变量T的转换。
从S到T的未经检查的强制转换是完全未选中,如果从 | S |至| T |从静态上讲是正确的。不然是 部分未选中。
未经检查的强制转换会导致编译时未经检查的警告,除非 被SuppressWarnings注释(第9.6.3.5节)取消。
如果不是静态已知正确且正确,则检查 未被选中。
如果强制转换为引用类型不是编译时错误,则存在 几种情况:
- 根据静态信息,演员表是正确的。
不对此类转换执行运行时操作。
- 演员表是完全未经检查的演员表。
不对此类转换执行运行时操作。
- 演员表是部分未经检查的演员表。
此类强制转换需要运行时有效性检查。执行检查 好像强制转换是| S |之间的选中强制转换和| T |,为 如下所述。
- 演员表是已检查的演员表。
此类强制转换需要运行时有效性检查。如果值在运行 时间为空,则允许强制转换。否则,让R为类 由运行时参考值引用的对象的,然后让T 是强制转换运算符中命名的类型的擦除(第4.6节)。演员表 转换必须在运行时检查类R是否为赋值 通过第5.5.3节中的算法与类型T兼容。
请注意,首次应用这些规则时,R不能是接口 对于任何给定的转换,但如果应用了规则,则R可能是接口 递归,因为运行时参考值可能引用数组 元素类型是接口类型。
答案 1 :(得分:0)
因为当您将Object
转换为A<String>
时,编译器无法检查Object
确实是{{1} },而不是A<String>
(或其他任何内容)。