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

Sha*_*n F 17 java generics collections

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

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

eri*_*son 16

与未指定泛型类型的类型参数的遗留代码进行互操作时,请使用通配符.例如,假设您正在调用一个只返回raw的旧库中的方法Collection:

Collection getItems();
Run Code Online (Sandbox Code Playgroud)

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

Collection<?> items = widget.getItems();
Run Code Online (Sandbox Code Playgroud)

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

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

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

在这种情况下,您可以选择.您可以将结果转换为a Collection<Item>,但是如果这样做,则您将100%依赖第三方库,并放弃Java泛型类型的保证:ClassCastException在运行时引发的任何内容都将在显式转换时生成.

如果您不完全信任第三方库,但仍需要生成一个Collection<Item>?然后创建一个新集合,并在将它们转换为期望的类型后添加内容.这样一来,如果库中有一个bug,你就会马上发现它,而不是让一些代码远离它,而后来很多东西神秘地爆炸了ClassCastException.

例如:

Collection<?> tmp = widget.getItems();
Collection<Item> items = new ArrayList<Item>(tmp.size());
for (Object o : tmp)
  items.add((Item) o); /* Any type error will be discovered here! */
Run Code Online (Sandbox Code Playgroud)

对于其中类型参数是不是在编译时已知的情况下,你可以使用类型检查收集工厂的的Collections类.


dav*_*veb 11

您可以简单地转换列表:

  List raw = new ArrayList();
  List<String> generic = (List<String>) raw;
Run Code Online (Sandbox Code Playgroud)

  • 如果列表确实保证包含一种类型的项目,这是一个很好的答案. (2认同)