在 Java 1.5 中将非泛型列表类型转换为泛型列表类型

2022-09-02 12:38:24

我有一个保证只包含一个类型对象的列表。这是由我无法更新的库中的一些基础代码创建的。我想基于传入的List对象创建一个List<ObjectType>以便我的调用代码正在与List<ObjectType>通信。

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


答案 1

使用未指定泛型类型类型参数的旧代码进行交互操作时,请使用通配符。例如,假设您正在调用旧库中的一个方法,该方法仅返回原始:Collection

Collection getItems();

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

Collection<?> items = widget.getItems();

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

旧代码可能会指定(最有可能在注释中)通用参数应该是什么。例如:

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

在这种情况下,您有一个选择。您可以将结果转换为 ,但如果您这样做,则 100% 依赖于第三方库,并放弃了 Java 泛型类型的保证:在运行时引发的任何值都将在显式强制转换时发生。Collection<Item>ClassCastException

如果您不完全信任第三方库,但仍需要生成 ?然后创建一个新集合,并在将内容转换为预期类型后添加内容。这样,如果库中有一个错误,你马上就会发现它,而不是在很远的地方有一些代码,然后神秘地用.Collection<Item>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! */

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


答案 2

您可以简单地投射列表:

  List raw = new ArrayList();
  List<String> generic = (List<String>) raw;