从Object转换为List的类型化实例的通用方法

时间:2015-02-27 13:40:35

标签: java list generics casting

我们假设,有一种方法可以返回Object,但我们知道它是某种类型的List(例如LinkedList<Long>ArrayList<String> ):

public abstract Object open();

直接使用其返回值

List<Long> result = (List<Long>)dialog.open();

会引发警告,例如:

类型安全:未选中从对象转换为列表


要解决此问题,我们可以转换为List<?>,然后分别检查每个列表项:

List<?> result = (List<?>)dialog.open();
List<Long> safeResult = new LinkedList<Long>();

for (Object obj: result) {
   if (obj instanceof Long) {
      safeResult.add((Long)obj);
   }
}

现在我想,拥有一个可以将Object(已知包含List)的通用方法强加给任何类型的{{1}实例并不是一件好事。 }}

这是我能得到的最接近的:

List

现在我可以像这样使用它:

private <T> List<T> doSafeCast(Object listObject, Class<T> type) {
  List<T> result = new LinkedList<T>();

  if (listObject instanceof List) {
     List<?> list = (List<?>)listObject;

     for (Object obj: list) {
        if (type.isInstance(obj)) {
           result.add(type.cast(obj));
        }
     }
  }

  return result;
}

但是,现在我必须只有List<Long> safeResult = this.doSafeCast(dialog.open(), Long.class); s。


是否可以通过传递其他参数来指定列表类型?

我想要这样的事情:

LinkedList

我知道所有这些看起来过于复杂,如果我确定对话框将始终返回所需类型,我可以将List<Long> safeResult = this.doSafeCast(dialog.open(), Long.class, ArrayList.class); List<String> anotherSafeResult = this.doSafeCast(anotherDialog.open(), String.class, LinkedList.class); 添加到我最初的不安全演员阵容中。但是我想出了一个通用方法来做这种安全演员的想法,现在我想知道,如果这是可能的话。所以请不要提出其他解决方案,我只是想了解一下如何使用泛型。 :-)谢谢。

1 个答案:

答案 0 :(得分:1)

是的,你可以。只需为方法引入另一个类型参数,然后将其上传到List

private <T, L extends List<T>> List<T> doSafeCast(Object listObject, 
                                                  Class<T> type, 
                                                  Class<L> listClass) {
    List<T> result = listClass.newInstance();

    if (listObject instanceof List) {
        List<?> list = (List<?>) listObject;

        for (Object obj : list) {
            if (type.isInstance(obj)) {
                result.add(type.cast(obj));
            }
        }
    }
    return result;
}

请注意,您必须处理几个可能的例外情况。