假设以下陈述有效:
Collection<SomeType> collection;
Collection<OtherType> otherCollection = (Collection<OtherType>) collection; //illegal
这将破坏应该提供的类型安全泛型。想象一下,您可以将 a 分配Collection<SomeType>给 a Collection<OtherType>。然后以下代码将允许您将不是 a 的内容SomeType放入 a Collection<SomeType>:
otherCollection.add(new OtherType());
因为otherCollection是 a Collection<OtherType>,添加 anew OtherType()似乎完全合法。但otherCollection实际上是指类型的集合SomeType。
这是允许的:
Collection<SomeType> collection;
Collection<OtherType> otherCollection = (Collection<OtherType>) (Collection<?>) collection;
这是 的一个含义type erasure。由于泛型几乎完全在 Java 编译器中实现,而不是在运行时中实现,所以几乎所有关于泛型类型erased的类型信息在生成字节码时就已经存在。所以在运行时,Collection<SomeType>andCollection<OtherType>是同一个类,它们都是Collection<?>. 通过这种转换,编译器将简单地发出未经检查的警告,因为它不知道强制转换是否安全。
但是,应该避免像您在第二个示例中给出的那样进行强制转换,以避免ClassCastException在运行时避免。考虑以下一系列语句:
Collection<SomeType> collection;
Collection<OtherType> otherCollection = (Collection<OtherType>) (Collection<?>) collection;
collection.add(new SomeType());
otherCollection.add(new OtherType());
现在在第 4 条语句之后,原始集合无法判断它包含哪些特定类型的对象;这可能会导致ClassCastException在运行时访问集合中的元素。