代码之家  ›  专栏  ›  技术社区  ›  Shaun Mundi

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

  •  17
  • Shaun Mundi  · 技术社区  · 15 年前

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

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

    5 回复  |  直到 13 年前
        1
  •  14
  •   erickson    15 年前

    当与没有为泛型类型指定类型参数的旧代码交互操作时,请使用通配符。例如,假设您正在调用旧库中的一个方法,该方法只返回一个原始的 Collection 以下内容:

    Collection getItems();
    

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

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

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

    遗留代码可能指定(在注释中,很可能)通用参数应该是什么。例如:

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

    在这种情况下,您有一个选择。你 可以 将结果强制转换为 Collection<Item> 但是,如果这样做,则依赖第100%方库,而放弃Java泛型类型的保证:即 ClassCastException 在运行时引发的将恰好发生在显式强制转换中。

    如果您不完全信任第三方库,但仍然需要生成 集合<项> ?然后创建一个新集合,并在将内容强制转换为预期类型后添加内容。这样,如果在库中有一个bug,您就可以立即发现它,而不是在很远的地方有一些代码,然后用一个 类别例外 .

    例如:

    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 Collections 班级。

        2
  •  11
  •   daveb    15 年前

    您可以简单地转换列表:

      List raw = new ArrayList();
      List<String> generic = (List<String>) raw;
    
        3
  •  1
  •   nanda    15 年前

    最好和最安全的方法是使用java.util.collections方法“checkedlist(list list,class type)”。

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

        4
  •  1
  •   andersoj    13 年前

    试试这个:

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

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

        5
  •  0
  •   Hakanai    15 年前

    如果你只是 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最终能获得运行时通用类型信息。

    推荐文章