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

时间:2009-09-30 15:43:14

标签: java generics collections

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

进行通信

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

5 个答案:

答案 0 :(得分:15)

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

Collection getItems();

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

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

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

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

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

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

如果您不完全信任第三方库,但仍需要生成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! */ 类的type-checked collection factories

答案 1 :(得分:11)

您可以简单地转换列表:

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

试试这个:

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

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

答案 4 :(得分:0)

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

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

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

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

理论上checkedList实用程序在理论上是一个好主意,但在实践中,必须通过你期望的课程。我希望Java最终能获得运行时通用的输入信息。