在Java 1.5中将非genericsList类型转换为Generic List类型

我有一个List,保证只包含一个类型对象。 这是由我无法更新的库中的某些底层代码创建的。 我想基于传入的List对象创建一个List ,以便我的调用代码与List 进行通信。

将List(或任何其他对象集合)转换为List 的最佳方法是什么。

在与未指定generics类型的类型参数的遗留代码进行交互操作时,请使用通配符。 例如,假设您在旧库中调用一个只返回原始Collection

 Collection getItems(); 

在您的代码中,将结果分配给使用通配符声明的变量:

 Collection items = widget.getItems(); 

这样,您可以保留类型安全性,这样您就不会收到任何警告。

遗留代码可能指定(在评论中,最有可能)通用参数应该是什么。 例如:

 /** * @return the items, as a Collection of {@link Item} instances. */ Collection getItems(); 

在这种情况下,您可以选择。 您可以将结果转换为Collection ,但是如果这样做,您将100%依赖第三方库,并放弃Javagenerics类型的保证:在运行时引发的任何ClassCastException都将发生在显性演员。

如果您不完全信任第三方库,但仍需要生成Collection怎么办? 然后创建一个新集合,并在将它们转换为期望的类型后添加内容。 这样一来,如果库中有一个bug,你就会马上发现它,而不是让一些代码远离它,然后很快就会出现ClassCastException

例如:

 Collection tmp = widget.getItems(); Collection items = new ArrayList(tmp.size()); for (Object o : tmp) items.add((Item) o); /* Any type error will be discovered here! */ 

对于在编译时未知类型参数的情况,可以使用Collections类的类型检查的集合工厂 。

您可以简单地转换列表:

  List raw = new ArrayList(); List generic = (List) raw; 

最好和最安全的方法是使用java.util.Collections方法’checkedList(列表列表,类类型)’

使用此方法,将尽早检查旧列表中的所有项目。

尝试这个:

 List objectsWithType = Arrays.asList((ObjectType[])wildcardObjects).toArray()); 

但请记住,这将产生一个固定长度的List。 如果您尝试在此列表中添加或删除元素,则会引发错误。 所以在使用Arrays.asList()要小心。

如果您只是在任何旧位置转换为List ,您将收到“未经检查”的编译器警告。 我们通过将其移动到实用方法来解决这个问题。

 public class Lists { @SuppressWarnings({"unchecked"}) public static  List cast(List list) { return (List) list; } } 

来电者现在没有警告,例如:

 for (Element child : Lists.cast(parent.getChildren())) { // ... } 

那个checkedList实用程序在理论上是一个好主意,但实际上很难传入你期望的类。 我希望Java最终能获得运行时通用的输入信息。