问题描述
定义了未经检查的转换,如下所示:
让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");
}
}
由于Object不是原始类型 (AFAIK),因此上述代码为何应生成未经检查的强制转换警告,并且在定义此行为的地方?
1楼
您正在查看错误的部分,这就是为什么在您的示例上下文中似乎没有意义的原因。
您的警告是未经检查的演员表 。 您正在查看未检查的转化 ( )部分。
从静态将类型S转换为类型T是正确的,当且仅当S <:T(第4.10节)。
除非至少满足以下条件之一,否则不检查从类型S到参数化类型(第4.5节)T的强制转换:
- S <:T
- T的所有类型参数(第4.5.1节)都是无界通配符
- T <:S和S除了T的类型参数中不包含X的类型参数以外,没有T的子类型X。
除非S <:T,否则不检查从类型S到类型变量T的转换。
如果从| S |强制转换,则从S到T的未检查强制转换将完全取消选中 。 至| T | 从静态上讲是正确的。 否则,将其部分取消选中 。
除非受到SuppressWarnings注释(第9.6.3.5节)的抑制,否则未经检查的强制转换会导致编译时未检查的警告。
如果不是从静态上知道正确的演员表,并且不是未选中的,则检查演员表。
如果强制转换为引用类型不是编译时错误,则有以下几种情况:
- 静态已知转换是正确的。
对于此类转换,不执行任何运行时操作。
- 演员表是完全未经检查的演员表。
对于此类转换,不执行任何运行时操作。
- 演员表是部分未经检查的演员表。
这种转换需要运行时有效性检查。 就像在| S |之间检查了演员表一样执行检查。 | T |,如下所述。
- 演员表为选中的演员表。
这种转换需要运行时有效性检查。 如果运行时的值为null,则允许强制转换。 否则,让R为运行时参考值引用的对象的类,让T为在强制转换运算符中命名的类型的擦除(第4.6节)。 强制转换必须在运行时通过第5.5.3节中的算法检查类R是否与类型T兼容。
请注意,当这些规则首次应用于任何给定的转换时,R不能是接口,但是如果递归应用这些规则,则R可以是接口,因为运行时参考值可能引用其元素类型为接口类型的数组。
2楼
因为当您将Object
转换为A<String>
,编译器无法检查(或生成要检查的代码)该Object
确实是A<String>
而不是A<Integer>
(或其他)。