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

标签 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 )到 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);

但是,现在我一定有LinkedList仅作为结果。

<小时/>

是否也可以通过传递附加参数来指定列表类型?

我想要这样的事情:

List<Long> safeResult = this.doSafeCast(dialog.open(), Long.class, ArrayList.class);

List<String> anotherSafeResult = this.doSafeCast(anotherDialog.open(), String.class, LinkedList.class);

我知道这一切看起来过于复杂,我可以添加 @SuppressWarnings("unchecked")如果我确定对话框将始终返回所需的类型,那么我最初的不安全转换。但我想出了一个想法,即有一个通用方法来进行此类安全转换,现在我想知道这是否可能。所以请不要建议其他解决方案,我只是想在这里更多地了解如何使用泛型。 :-) 谢谢。

最佳答案

是的,可以。只需为该方法引入另一个类型参数并将其向上绑定(bind)到 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;
}

请注意,您必须处理一些可能的异常。

关于java - 从 Object 转换为 List 的类型化实例的通用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28766478/

相关文章:

java - 我收到了关于计算每小时英里数的作业,但我的运行程序似乎无法找到我的时间变量

java - 为什么在这种情况下不会发生自动装箱?

python - 列表上的循环操作仅对第一项无法正确执行

python - 如何在线性时间内根据键重新组合列表列表?

javascript - Typescript 中泛型类中 Type 的默认值

C# 无法从 `Inherited Class` 转换为 `Base Class`

java - 如何使用虚拟目的地创建多个 activemq 主题订阅者实例?

java - 查找某个项目在数组中出现的次数

带有按钮 : Disable button after click 的 AngularJS ng-repeat 列表

C# - 使用反射从列表<Class>中提取值列表