假设以下陈述有效:
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
在运行时访问集合中的元素。